diff options
33 files changed, 400 insertions, 308 deletions
diff --git a/Docs/source/developers/warning_logger.rst b/Docs/source/developers/warning_logger.rst index c08039e00..057aa21bb 100644 --- a/Docs/source/developers/warning_logger.rst +++ b/Docs/source/developers/warning_logger.rst @@ -68,14 +68,15 @@ In the code, instead of using ``amrex::Warning`` to immediately print a warning .. code-block:: cpp - WarpX::GetInstance().RecordWarning( + ablastr::warn_manager::WMRecordWarning( "QED", "Using default value (2*me*c^2) for photon energy creation threshold", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); -In this example, ``QED`` is the topic, ``Using [...]`` is the warning message and ``WarnPriority::low`` is the priority. +In this example, ``QED`` is the topic, ``Using [...]`` is the warning message and ``ablastr::warn_manager::WarnPriority::low`` is the priority. `RecordWarning` is **not** a collective call and should also be thread-safe (it can be called in OpenMP loops). In case the user wants to also print the warning messages immediately, the runtime parameter ``warpx.always_warn_immediately`` can be set to ``1``. +The Warning manager is a singleton class defined in ``Source/ablastr/warn_manager/WarnManager.H``` How to print the warning list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -84,7 +85,7 @@ The warning list can be printed as follows: .. code-block:: cpp - warpx.PrintGlobalWarnings("THE END"); + amrex::Print() << ablastr::warn_manager::GetWMInstance().PrintGlobalWarnings("THE END"); where the string is a temporal marker that appears in the warning list. At the moment this is done right after step one and at the end of the simulation. diff --git a/Source/Diagnostics/Diagnostics.cpp b/Source/Diagnostics/Diagnostics.cpp index 55bc24f87..69547d6bb 100644 --- a/Source/Diagnostics/Diagnostics.cpp +++ b/Source/Diagnostics/Diagnostics.cpp @@ -19,6 +19,8 @@ #include "Utils/WarpXUtil.H" #include "WarpX.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX.H> #include <AMReX_BLassert.H> #include <AMReX_Config.H> @@ -338,7 +340,7 @@ Diagnostics::InitData () std::string warnMsg = "For full diagnostics on a reduced domain, particle I/O is not "; warnMsg += "supported, yet! Therefore, particle I/O is disabled for this diagnostics: "; warnMsg += m_diag_name; - WarpX::GetInstance().RecordWarning("Diagnostics", warnMsg); + ablastr::warn_manager::WMRecordWarning("Diagnostics", warnMsg); } } } diff --git a/Source/Diagnostics/FlushFormats/FlushFormatOpenPMD.cpp b/Source/Diagnostics/FlushFormats/FlushFormatOpenPMD.cpp index 4c31dbecd..e7874c4ff 100644 --- a/Source/Diagnostics/FlushFormats/FlushFormatOpenPMD.cpp +++ b/Source/Diagnostics/FlushFormats/FlushFormatOpenPMD.cpp @@ -4,6 +4,8 @@ #include "Utils/WarpXProfilerWrapper.H" #include "WarpX.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX.H> #include <AMReX_BLassert.H> #include <AMReX_ParmParse.H> @@ -44,7 +46,7 @@ FlushFormatOpenPMD::FlushFormatOpenPMD (const std::string& diag_name) ( openPMD::IterationEncoding::groupBased != encoding ) ) { std::string warnMsg = diag_name+" Unable to support BTD with streaming. Using GroupBased "; - WarpX::GetInstance().RecordWarning("Diagnostics", warnMsg); + ablastr::warn_manager::WMRecordWarning("Diagnostics", warnMsg); encoding = openPMD::IterationEncoding::groupBased; } } diff --git a/Source/Diagnostics/ReducedDiags/FieldProbe.cpp b/Source/Diagnostics/ReducedDiags/FieldProbe.cpp index 3d9582a2c..d5541b7ac 100644 --- a/Source/Diagnostics/ReducedDiags/FieldProbe.cpp +++ b/Source/Diagnostics/ReducedDiags/FieldProbe.cpp @@ -17,6 +17,8 @@ #include "Utils/WarpXUtil.H" #include "WarpX.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX_Array.H> #include <AMReX_Config.H> #include <AMReX_MFIter.H> @@ -154,10 +156,10 @@ FieldProbe::FieldProbe (std::string rd_name) if (WarpX::gamma_boost > 1.0_rt) { - WarpX::GetInstance().RecordWarning( + ablastr::warn_manager::WMRecordWarning( "Boosted Frame Invalid", "The FieldProbe Diagnostic will not record lab-frame, but boosted frame data.", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); } WARPX_ALWAYS_ASSERT_WITH_MESSAGE(interp_order <= WarpX::nox , diff --git a/Source/Diagnostics/SliceDiagnostic.cpp b/Source/Diagnostics/SliceDiagnostic.cpp index 407b66325..7cd475c46 100644 --- a/Source/Diagnostics/SliceDiagnostic.cpp +++ b/Source/Diagnostics/SliceDiagnostic.cpp @@ -11,6 +11,8 @@ #include "Utils/TextMsg.H" #include "Parallelization/WarpXCommUtil.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX.H> #include <AMReX_Array4.H> #include <AMReX_BLassert.H> @@ -28,7 +30,6 @@ #include <AMReX_MultiFab.H> #include <AMReX_MultiFabUtil.H> #include <AMReX_PlotFileUtil.H> - #include <AMReX_Print.H> #include <AMReX_REAL.H> #include <AMReX_RealBox.H> @@ -126,7 +127,7 @@ CreateSlice( const MultiFab& mf, const Vector<Geometry> &dom_geom, } } if (configuration_dim==1) { - WarpX::GetInstance().RecordWarning("Diagnostics", + ablastr::warn_manager::WMRecordWarning("Diagnostics", "The slice configuration is 1D and cannot be visualized using yt."); } @@ -288,8 +289,8 @@ CheckSliceInput( const RealBox real_box, RealBox &slice_cc_nd_box, warnMsg << " slice lo is out of bounds. " << " Modified it in dimension " << idim << " to be aligned with the domain box."; - WarpX::GetInstance().RecordWarning("Diagnostics", - warnMsg.str(), WarnPriority::low); + ablastr::warn_manager::WMRecordWarning("Diagnostics", + warnMsg.str(), ablastr::warn_manager::WarnPriority::low); } // Modify hi if input in out od bounds // @@ -299,8 +300,8 @@ CheckSliceInput( const RealBox real_box, RealBox &slice_cc_nd_box, warnMsg << " slice hi is out of bounds. " << " Modified it in dimension " << idim << " to be aligned with the domain box."; - WarpX::GetInstance().RecordWarning("Diagnostics", - warnMsg.str(), WarnPriority::low); + ablastr::warn_manager::WMRecordWarning("Diagnostics", + warnMsg.str(), ablastr::warn_manager::WarnPriority::low); } // Factor to ensure index values computation depending on index type // @@ -388,7 +389,7 @@ CheckSliceInput( const RealBox real_box, RealBox &slice_cc_nd_box, warnMsg << " Coarsening ratio " << slice_cr_ratio[idim] << " in dim "<< idim << "is leading to zero cells for slice." << " Thus reducing cr_ratio by half.\n"; - WarpX::GetInstance().RecordWarning("Diagnostics", + ablastr::warn_manager::WMRecordWarning("Diagnostics", warnMsg.str()); slice_cr_ratio[idim] = slice_cr_ratio[idim]/2; diff --git a/Source/Diagnostics/WarpXOpenPMD.cpp b/Source/Diagnostics/WarpXOpenPMD.cpp index c5d882083..6e73ab55d 100644 --- a/Source/Diagnostics/WarpXOpenPMD.cpp +++ b/Source/Diagnostics/WarpXOpenPMD.cpp @@ -17,6 +17,7 @@ #include "WarpX.H" #include <ablastr/particles/IndexHandling.H> +#include <ablastr/warn_manager/WarnManager.H> #include <AMReX.H> #include <AMReX_ArrayOfStructs.H> @@ -463,7 +464,7 @@ void WarpXOpenPMDPlot::SetStep (int ts, const std::string& dirPrefix, int file_m if (m_CurrentStep >= ts) { // note m_Series is reset in Init(), so using m_Series->iterations.contains(ts) is only able to check the // last written step in m_Series's life time, but not other earlier written steps by other m_Series - WarpX::GetInstance().RecordWarning("Diagnostics", + ablastr::warn_manager::WMRecordWarning("Diagnostics", " Warning from openPMD writer: Already written iteration:" + std::to_string(ts) ); diff --git a/Source/EmbeddedBoundary/WarpXFaceExtensions.cpp b/Source/EmbeddedBoundary/WarpXFaceExtensions.cpp index 772cc9b46..dbfebda66 100644 --- a/Source/EmbeddedBoundary/WarpXFaceExtensions.cpp +++ b/Source/EmbeddedBoundary/WarpXFaceExtensions.cpp @@ -5,17 +5,16 @@ * License: BSD-3-Clause-LBNL */ -#include "WarpX.H" - #include "WarpXFaceInfoBox.H" - #include "Utils/TextMsg.H" +#include "WarpX.H" + +#include <ablastr/warn_manager/WarnManager.H> #include <AMReX_Scan.H> #include <AMReX_iMultiFab.H> #include <AMReX_MultiFab.H> - /** * \brief Get the value of arr in the neighbor (i_n, j_n) on the plane with normal 'dim'. * @@ -184,39 +183,39 @@ void WarpX::ComputeFaceExtensions(){ #ifdef AMREX_USE_EB amrex::Array1D<int, 0, 2> N_ext_faces = CountExtFaces(); - WarpX::RecordWarning("Embedded Boundary", + ablastr::warn_manager::WMRecordWarning("Embedded Boundary", "Faces to be extended in x:\t" + std::to_string(N_ext_faces(0)) + "\n" +"Faces to be extended in y:\t" + std::to_string(N_ext_faces(1)) + "\n" +"Faces to be extended in z:\t" + std::to_string(N_ext_faces(2)), - WarnPriority::low + ablastr::warn_manager::WarnPriority::low ); InitBorrowing(); ComputeOneWayExtensions(); amrex::Array1D<int, 0, 2> N_ext_faces_after_one_way = CountExtFaces(); - WarpX::RecordWarning("Embedded Boundary", + ablastr::warn_manager::WMRecordWarning("Embedded Boundary", "Faces to be extended after one way extension in x:\t" + std::to_string(N_ext_faces_after_one_way(0)) + "\n" +"Faces to be extended after one way extension in y:\t" + std::to_string(N_ext_faces_after_one_way(1)) + "\n" +"Faces to be extended after one way extension in z:\t" + std::to_string(N_ext_faces_after_one_way(2)), - WarnPriority::low + ablastr::warn_manager::WarnPriority::low ); ComputeEightWaysExtensions(); ShrinkBorrowing(); amrex::Array1D<int, 0, 2> N_ext_faces_after_eight_ways = CountExtFaces(); - WarpX::RecordWarning("Embedded Boundary", + ablastr::warn_manager::WMRecordWarning("Embedded Boundary", "Faces to be extended after eight ways extension in x:\t" + std::to_string(N_ext_faces_after_eight_ways(0)) + "\n" +"Faces to be extended after eight ways extension in y:\t" + std::to_string(N_ext_faces_after_eight_ways(1)) + "\n" +"Faces to be extended after eight ways extension in z:\t" + std::to_string(N_ext_faces_after_eight_ways(2)), - WarnPriority::low + ablastr::warn_manager::WarnPriority::low ); bool using_bck = false; @@ -242,13 +241,13 @@ WarpX::ComputeFaceExtensions(){ #endif if(using_bck) { - WarpX::RecordWarning("Embedded Boundary", + ablastr::warn_manager::WMRecordWarning("Embedded Boundary", "Some faces could not be stabilized with the ECT and the BCK correction was used.\n" "The BCK correction will be used for:\n" "-" + std::to_string(N_ext_faces_after_eight_ways(0)) + " x-faces\n" + "-" + std::to_string(N_ext_faces_after_eight_ways(1)) + " y-faces\n" + "-" + std::to_string(N_ext_faces_after_eight_ways(2)) + " z-faces\n", - WarnPriority::low + ablastr::warn_manager::WarnPriority::low ); } #endif diff --git a/Source/Evolve/WarpXEvolve.cpp b/Source/Evolve/WarpXEvolve.cpp index 4c7eec664..f150d5098 100644 --- a/Source/Evolve/WarpXEvolve.cpp +++ b/Source/Evolve/WarpXEvolve.cpp @@ -34,6 +34,7 @@ #include "Utils/WarpXUtil.H" #include <ablastr/utils/SignalHandling.H> +#include <ablastr/warn_manager/WarnManager.H> #include <AMReX.H> #include <AMReX_Array.H> @@ -342,7 +343,10 @@ WarpX::Evolve (int numsteps) if (!early_params_checked) { amrex::Print() << "\n"; // better: conditional \n based on return value amrex::ParmParse().QueryUnusedInputs(); - this->PrintGlobalWarnings("FIRST STEP"); //Print the warning list right after the first step. + + //Print the warning list right after the first step. + amrex::Print() << + ablastr::warn_manager::GetWMInstance().PrintGlobalWarnings("FIRST STEP"); early_params_checked = true; } diff --git a/Source/FieldSolver/ElectrostaticSolver.cpp b/Source/FieldSolver/ElectrostaticSolver.cpp index ba462004a..54def35da 100644 --- a/Source/FieldSolver/ElectrostaticSolver.cpp +++ b/Source/FieldSolver/ElectrostaticSolver.cpp @@ -18,6 +18,8 @@ #include "Utils/WarpXProfilerWrapper.H" #include "Parallelization/WarpXCommUtil.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX_Array.H> #include <AMReX_Array4.H> #include <AMReX_BLassert.H> @@ -284,8 +286,9 @@ WarpX::computePhi (const amrex::Vector<std::unique_ptr<amrex::MultiFab> >& rho, bool always_use_bnorm = (max_norm_b > 0); if (!always_use_bnorm) { if (absolute_tolerance == 0.0) absolute_tolerance = amrex::Real(1e-6); - WarpX::GetInstance().RecordWarning( - "ElectrostaticSolver", "Max norm of rho is 0", WarnPriority::low + ablastr::warn_manager::WMRecordWarning( + "ElectrostaticSolver", "Max norm of rho is 0", + ablastr::warn_manager::WarnPriority::low ); } diff --git a/Source/FieldSolver/FiniteDifferenceSolver/MacroscopicProperties/MacroscopicProperties.cpp b/Source/FieldSolver/FiniteDifferenceSolver/MacroscopicProperties/MacroscopicProperties.cpp index 0cfe25e08..438e237fb 100644 --- a/Source/FieldSolver/FiniteDifferenceSolver/MacroscopicProperties/MacroscopicProperties.cpp +++ b/Source/FieldSolver/FiniteDifferenceSolver/MacroscopicProperties/MacroscopicProperties.cpp @@ -4,6 +4,8 @@ #include "Utils/WarpXUtil.H" #include "WarpX.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX_Array4.H> #include <AMReX_BoxArray.H> #include <AMReX_Config.H> @@ -53,7 +55,7 @@ MacroscopicProperties::ReadParameters () std::stringstream warnMsg; warnMsg << "Material conductivity is not specified. Using default vacuum value of " << m_sigma << " in the simulation."; - WarpX::GetInstance().RecordWarning("Macroscopic properties", + ablastr::warn_manager::WMRecordWarning("Macroscopic properties", warnMsg.str()); } // initialization of sigma (conductivity) with parser @@ -76,7 +78,7 @@ MacroscopicProperties::ReadParameters () std::stringstream warnMsg; warnMsg << "Material permittivity is not specified. Using default vacuum value of " << m_epsilon << " in the simulation."; - WarpX::GetInstance().RecordWarning("Macroscopic properties", + ablastr::warn_manager::WMRecordWarning("Macroscopic properties", warnMsg.str()); } @@ -101,7 +103,7 @@ MacroscopicProperties::ReadParameters () std::stringstream warnMsg; warnMsg << "Material permittivity is not specified. Using default vacuum value of " << m_mu << " in the simulation."; - WarpX::GetInstance().RecordWarning("Macroscopic properties", + ablastr::warn_manager::WMRecordWarning("Macroscopic properties", warnMsg.str()); } diff --git a/Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp b/Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp index b81594628..5a2f1d643 100644 --- a/Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp +++ b/Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp @@ -9,6 +9,8 @@ #include "WarpX.H" #include "Utils/WarpXUtil.H" +#include <ablastr/warn_manager/WarnManager.H> + using amrex::operator""_rt; /* \brief Initialize fields in spectral space, and FFT plans @@ -88,8 +90,8 @@ SpectralFieldDataRZ::SpectralFieldDataRZ (const int lev, result = cufftPlanMany(&forward_plan[mfi], 1, fft_length, inembed, istride, idist, onembed, ostride, odist, cufft_type, batch); if (result != CUFFT_SUCCESS) { - WarpX::GetInstance().RecordWarning("Spectral solver", - "cufftPlanMany failed!", WarnPriority::high); + ablastr::warn_manager::WMRecordWarning("Spectral solver", + "cufftPlanMany failed!", ablastr::warn_manager::WarnPriority::high); } // The backward plane is the same as the forward since the direction is passed when executed. #elif defined(AMREX_USE_HIP) @@ -117,8 +119,9 @@ SpectralFieldDataRZ::SpectralFieldDataRZ (const int lev, grid_size[0], // number of transforms description); if (result != rocfft_status_success) { - WarpX::GetInstance().RecordWarning("Spectral solver", - "rocfft_plan_create failed!\n", WarnPriority::high); + ablastr::warn_manager::WMRecordWarning("Spectral solver", + "rocfft_plan_create failed!\n", + ablastr::warn_manager::WarnPriority::high); } result = rocfft_plan_create(&(backward_plan[mfi]), @@ -133,14 +136,16 @@ SpectralFieldDataRZ::SpectralFieldDataRZ (const int lev, grid_size[0], // number of transforms description); if (result != rocfft_status_success) { - WarpX::GetInstance().RecordWarning("Spectral solver", - "rocfft_plan_create failed!\n", WarnPriority::high); + ablastr::warn_manager::WMRecordWarning("Spectral solver", + "rocfft_plan_create failed!\n", + ablastr::warn_manager::WarnPriority::high); } result = rocfft_plan_description_destroy(description); if (result != rocfft_status_success) { - WarpX::GetInstance().RecordWarning("Spectral solver", - "rocfft_plan_description_destroy failed!\n", WarnPriority::high); + ablastr::warn_manager::WMRecordWarning("Spectral solver", + "rocfft_plan_description_destroy failed!\n", + ablastr::warn_manager::WarnPriority::high); } #else // Create FFTW plans. @@ -246,8 +251,9 @@ SpectralFieldDataRZ::FABZForwardTransform (amrex::MFIter const & mfi, amrex::Box reinterpret_cast<AnyFFT::Complex*>(tmpSpectralField[mfi].dataPtr(mode)), // Complex *out CUFFT_FORWARD); if (result != CUFFT_SUCCESS) { - WarpX::GetInstance().RecordWarning("Spectral solver", - "forward transform using cufftExecZ2Z failed!", WarnPriority::high); + ablastr::warn_manager::WMRecordWarning("Spectral solver", + "forward transform using cufftExecZ2Z failed!", + ablastr::warn_manager::WarnPriority::high); } } #elif defined(AMREX_USE_HIP) @@ -264,8 +270,9 @@ SpectralFieldDataRZ::FABZForwardTransform (amrex::MFIter const & mfi, amrex::Box void* out_array[] = {(void*)(tmpSpectralField[mfi].dataPtr(mode))}; result = rocfft_execute(forward_plan[mfi], in_array, out_array, execinfo); if (result != rocfft_status_success) { - WarpX::GetInstance().RecordWarning("Spectral solver", - "forward transform using rocfft_execute failed!", WarnPriority::high); + ablastr::warn_manager::WMRecordWarning("Spectral solver", + "forward transform using rocfft_execute failed!", + ablastr::warn_manager::WarnPriority::high); } } @@ -357,8 +364,9 @@ SpectralFieldDataRZ::FABZBackwardTransform (amrex::MFIter const & mfi, amrex::Bo reinterpret_cast<AnyFFT::Complex*>(tempHTransformed[mfi].dataPtr(mode)), // Complex *out CUFFT_INVERSE); if (result != CUFFT_SUCCESS) { - WarpX::GetInstance().RecordWarning("Spectral solver", - "backwardtransform using cufftExecZ2Z failed!", WarnPriority::high); + ablastr::warn_manager::WMRecordWarning("Spectral solver", + "backwardtransform using cufftExecZ2Z failed!", + ablastr::warn_manager::WarnPriority::high); } } #elif defined(AMREX_USE_HIP) @@ -375,8 +383,9 @@ SpectralFieldDataRZ::FABZBackwardTransform (amrex::MFIter const & mfi, amrex::Bo void* out_array[] = {(void*)(tempHTransformed[mfi].dataPtr(mode))}; result = rocfft_execute(backward_plan[mfi], in_array, out_array, execinfo); if (result != rocfft_status_success) { - WarpX::GetInstance().RecordWarning("Spectral solver", - "forward transform using rocfft_execute failed!", WarnPriority::high); + ablastr::warn_manager::WMRecordWarning("Spectral solver", + "forward transform using rocfft_execute failed!", + ablastr::warn_manager::WarnPriority::high); } } diff --git a/Source/Initialization/PlasmaInjector.cpp b/Source/Initialization/PlasmaInjector.cpp index 58ecfd832..9dc4692f7 100644 --- a/Source/Initialization/PlasmaInjector.cpp +++ b/Source/Initialization/PlasmaInjector.cpp @@ -20,6 +20,8 @@ #include "Utils/WarpXUtil.H" #include "WarpX.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX.H> #include <AMReX_BLassert.H> #include <AMReX_Config.H> @@ -141,7 +143,7 @@ PlasmaInjector::PlasmaInjector (int ispecies, const std::string& name) bool mass_is_specified = queryWithParser(pp_species_name, "mass", mass); if ( charge_is_specified && species_is_specified ){ - WarpX::GetInstance().RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "Both '" + species_name + ".charge' and " + species_name + ".species_type' are specified.\n" + species_name + ".charge' will take precedence.\n"); @@ -155,7 +157,7 @@ PlasmaInjector::PlasmaInjector (int ispecies, const std::string& name) ); if ( mass_is_specified && species_is_specified ){ - WarpX::GetInstance().RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "Both '" + species_name + ".mass' and " + species_name + ".species_type' are specified.\n" + species_name + ".mass' will take precedence.\n"); @@ -397,13 +399,13 @@ PlasmaInjector::PlasmaInjector (int ispecies, const std::string& name) "'" + ps_name + ".species_type' in your input file!\n"); if (charge_is_specified) { - WarpX::GetInstance().RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "Both '" + ps_name + ".charge' and '" + ps_name + ".injection_file' specify a charge.\n'" + ps_name + ".charge' will take precedence.\n"); } else if (species_is_specified) { - WarpX::GetInstance().RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "Both '" + ps_name + ".species_type' and '" + ps_name + ".injection_file' specify a charge.\n'" + ps_name + ".species_type' will take precedence.\n"); @@ -416,13 +418,13 @@ PlasmaInjector::PlasmaInjector (int ispecies, const std::string& name) charge = p_q * charge_unit; } if (mass_is_specified) { - WarpX::GetInstance().RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "Both '" + ps_name + ".mass' and '" + ps_name + ".injection_file' specify a charge.\n'" + ps_name + ".mass' will take precedence.\n"); } else if (species_is_specified) { - WarpX::GetInstance().RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "Both '" + ps_name + ".species_type' and '" + ps_name + ".injection_file' specify a mass.\n'" + ps_name + ".species_type' will take precedence.\n"); diff --git a/Source/Initialization/TemperatureProperties.cpp b/Source/Initialization/TemperatureProperties.cpp index 9446f72d5..901275b04 100644 --- a/Source/Initialization/TemperatureProperties.cpp +++ b/Source/Initialization/TemperatureProperties.cpp @@ -8,7 +8,8 @@ #include "TemperatureProperties.H" #include "Utils/TextMsg.H" -#include "WarpX.H" + +#include <ablastr/warn_manager/WarnManager.H> /* * Construct TemperatureProperties based on the passed parameters. @@ -43,7 +44,7 @@ TemperatureProperties::TemperatureProperties (amrex::ParmParse& pp) { if (mom_dist_s == "maxwell_boltzmann" && theta > 0.01) { - WarpX::GetInstance().RecordWarning( + ablastr::warn_manager::WMRecordWarning( "Temperature", std::string{"Maxwell-Boltzmann distribution has errors greater than 1%"} + std::string{" for temperature parameter theta > 0.01. (theta = "} + diff --git a/Source/Initialization/WarpXInitData.cpp b/Source/Initialization/WarpXInitData.cpp index f7179deaf..8b7ad5e8d 100644 --- a/Source/Initialization/WarpXInitData.cpp +++ b/Source/Initialization/WarpXInitData.cpp @@ -29,6 +29,8 @@ #include "Utils/WarpXProfilerWrapper.H" #include "Utils/WarpXUtil.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX.H> #include <AMReX_AmrCore.H> #ifdef AMREX_USE_SENSEI_INSITU @@ -1099,7 +1101,8 @@ WarpX::PerformanceHints () << " More information:\n" << " https://warpx.readthedocs.io/en/latest/running_cpp/parallelization.html\n"; - WarpX::GetInstance().RecordWarning("Performance", warnMsg.str(), WarnPriority::high); + ablastr::warn_manager::WMRecordWarning( + "Performance", warnMsg.str(), ablastr::warn_manager::WarnPriority::high); } // TODO: warn if some ranks have disproportionally more work than all others @@ -1194,9 +1197,9 @@ void WarpX::InitializeEBGridData (int lev) if ((nox > 1 or noy > 1 or noz > 1) and flag_eb_on) { - this->RecordWarning("Particles", - "when algo.particle_shape > 1, numerical artifacts will be present when\n" - "particles are close to embedded boundaries"); + ablastr::warn_manager::WMRecordWarning("Particles", + "when algo.particle_shape > 1, numerical artifacts will be present when\n" + "particles are close to embedded boundaries"); } if (WarpX::maxwell_solver_id == MaxwellSolverAlgo::Yee || diff --git a/Source/Laser/LaserProfilesImpl/LaserProfileFromTXYEFile.cpp b/Source/Laser/LaserProfilesImpl/LaserProfileFromTXYEFile.cpp index 6d38a0b2f..b9ff9d519 100644 --- a/Source/Laser/LaserProfilesImpl/LaserProfileFromTXYEFile.cpp +++ b/Source/Laser/LaserProfilesImpl/LaserProfileFromTXYEFile.cpp @@ -9,7 +9,8 @@ #include "Utils/TextMsg.H" #include "Utils/WarpXUtil.H" #include "Utils/WarpX_Complex.H" -#include "WarpX.H" + +#include <ablastr/warn_manager/WarnManager.H> #include <AMReX.H> #include <AMReX_Algorithm.H> @@ -47,10 +48,10 @@ WarpXLaserProfiles::FromTXYEFileLaserProfile::init ( { if (!std::numeric_limits< double >::is_iec559) { - WarpX::GetInstance().RecordWarning("Laser", + ablastr::warn_manager::WMRecordWarning("Laser", "(Double does not comply with IEEE 754: bad" "things will happen parsing the X, Y and T profiles for the laser!)", - WarnPriority::high); + ablastr::warn_manager::WarnPriority::high); } // Parse the TXYE file diff --git a/Source/Particles/LaserParticleContainer.cpp b/Source/Particles/LaserParticleContainer.cpp index fbe2b9710..dae759cee 100644 --- a/Source/Particles/LaserParticleContainer.cpp +++ b/Source/Particles/LaserParticleContainer.cpp @@ -18,7 +18,8 @@ #include "Utils/WarpXConst.H" #include "Utils/WarpXProfilerWrapper.H" #include "Utils/WarpXUtil.H" -#include "WarpX.H" + +#include <ablastr/warn_manager/WarnManager.H> #include <AMReX.H> #include <AMReX_BLassert.H> @@ -117,9 +118,9 @@ LaserParticleContainer::LaserParticleContainer (AmrCore* amr_core, int ispecies, pp_laser_name.query("min_particles_per_mode", m_min_particles_per_mode); if (m_e_max == amrex::Real(0.)){ - WarpX::GetInstance().RecordWarning("Laser", + ablastr::warn_manager::WMRecordWarning("Laser", m_laser_name + " with zero amplitude disabled.", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); m_enabled = false; return; // Disable laser if amplitude is 0 } @@ -328,9 +329,9 @@ LaserParticleContainer::InitData () InitData(maxLevel()); if(!do_continuous_injection && (TotalNumberOfParticles() == 0)){ - WarpX::GetInstance().RecordWarning("Laser", + ablastr::warn_manager::WMRecordWarning("Laser", "The antenna is completely out of the simulation box for laser " + m_laser_name, - WarnPriority::high); + ablastr::warn_manager::WarnPriority::high); m_enabled = false; // Disable laser if antenna is completely out of the simulation box } } diff --git a/Source/Particles/MultiParticleContainer.cpp b/Source/Particles/MultiParticleContainer.cpp index 6349fe3d9..3805824a0 100644 --- a/Source/Particles/MultiParticleContainer.cpp +++ b/Source/Particles/MultiParticleContainer.cpp @@ -41,6 +41,8 @@ #include "WarpX.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX.H> #include <AMReX_Array.H> #include <AMReX_Array4.H> @@ -1025,9 +1027,9 @@ void MultiParticleContainer::InitQuantumSync () m_quantum_sync_photon_creation_energy_threshold = temp; } else{ - WarpX::GetInstance().RecordWarning("QED", + ablastr::warn_manager::WMRecordWarning("QED", "Using default value (2*me*c^2) for photon energy creation threshold", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); } // qs_minimum_chi_part is the minimum chi parameter to be @@ -1043,9 +1045,9 @@ void MultiParticleContainer::InitQuantumSync () } if(lookup_table_mode == "generate"){ - WarpX::GetInstance().RecordWarning("QED", + ablastr::warn_manager::WMRecordWarning("QED", "A new Quantum Synchrotron table will be generated.", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); #ifndef WARPX_QED_TABLE_GEN amrex::Error("Error: Compile with QED_TABLE_GEN=TRUE to enable table generation!\n"); #else @@ -1055,9 +1057,9 @@ void MultiParticleContainer::InitQuantumSync () else if(lookup_table_mode == "load"){ std::string load_table_name; pp_qed_qs.query("load_table_from", load_table_name); - WarpX::GetInstance().RecordWarning("QED", + ablastr::warn_manager::WMRecordWarning("QED", "The Quantum Synchrotron table will be read from the file: " + load_table_name, - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); if(load_table_name.empty()){ amrex::Abort("Quantum Synchrotron table name should be provided"); } @@ -1068,10 +1070,10 @@ void MultiParticleContainer::InitQuantumSync () qs_minimum_chi_part); } else if(lookup_table_mode == "builtin"){ - WarpX::GetInstance().RecordWarning("QED", + ablastr::warn_manager::WMRecordWarning("QED", "The built-in Quantum Synchrotron table will be used. " "This low resolution table is intended for testing purposes only.", - WarnPriority::medium); + ablastr::warn_manager::WarnPriority::medium); m_shr_p_qs_engine->init_builtin_tables(qs_minimum_chi_part); } else{ @@ -1101,9 +1103,9 @@ void MultiParticleContainer::InitBreitWheeler () } if(lookup_table_mode == "generate"){ - WarpX::GetInstance().RecordWarning("QED", + ablastr::warn_manager::WMRecordWarning("QED", "A new Breit Wheeler table will be generated.", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); #ifndef WARPX_QED_TABLE_GEN amrex::Error("Error: Compile with QED_TABLE_GEN=TRUE to enable table generation!\n"); #else @@ -1113,9 +1115,9 @@ void MultiParticleContainer::InitBreitWheeler () else if(lookup_table_mode == "load"){ std::string load_table_name; pp_qed_bw.query("load_table_from", load_table_name); - WarpX::GetInstance().RecordWarning("QED", + ablastr::warn_manager::WMRecordWarning("QED", "The Breit Wheeler table will be read from the file:" + load_table_name, - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); if(load_table_name.empty()){ amrex::Abort("Breit Wheeler table name should be provided"); } @@ -1126,10 +1128,10 @@ void MultiParticleContainer::InitBreitWheeler () table_data, bw_minimum_chi_part); } else if(lookup_table_mode == "builtin"){ - WarpX::GetInstance().RecordWarning("QED", + ablastr::warn_manager::WMRecordWarning("QED", "The built-in Breit Wheeler table will be used. " "This low resolution table is intended for testing purposes only.", - WarnPriority::medium); + ablastr::warn_manager::WarnPriority::medium); m_shr_p_bw_engine->init_builtin_tables(bw_minimum_chi_part); } else{ diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index 20632ce1f..762b5080e 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -39,6 +39,8 @@ #include "Utils/WarpXUtil.H" #include "WarpX.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX.H> #include <AMReX_Algorithm.H> #include <AMReX_Array.H> @@ -578,7 +580,7 @@ PhysicalParticleContainer::AddPlasmaFromFile(ParticleReal q_tot, ss << "Both '" << ps_name << ".q_tot' and '" << ps_name << ".injection_file' specify a total charge.\n'" << ps_name << ".q_tot' will take precedence."; - WarpX::GetInstance().RecordWarning("Species", ss.str()); + ablastr::warn_manager::WMRecordWarning("Species", ss.str()); } } // ED-PIC extension? @@ -617,9 +619,9 @@ PhysicalParticleContainer::AddPlasmaFromFile(ParticleReal q_tot, } auto const np = particle_z.size(); if (np < npart) { - WarpX::GetInstance().RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "Simulation box doesn't cover all particles", - WarnPriority::high); + ablastr::warn_manager::WarnPriority::high); } } // IO Processor auto const np = particle_z.size(); @@ -2727,7 +2729,7 @@ PhysicalParticleContainer::InitIonizationModule () if (!do_field_ionization) return; ParmParse pp_species_name(species_name); if (charge != PhysConst::q_e){ - WarpX::GetInstance().RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "charge != q_e for ionizable species '" + species_name + "':" + "overriding user value and setting charge = q_e."); diff --git a/Source/Particles/Resampling/LevelingThinning.cpp b/Source/Particles/Resampling/LevelingThinning.cpp index 842c28884..cf9ca9ba9 100644 --- a/Source/Particles/Resampling/LevelingThinning.cpp +++ b/Source/Particles/Resampling/LevelingThinning.cpp @@ -10,7 +10,8 @@ #include "Utils/ParticleUtils.H" #include "Utils/TextMsg.H" #include "Utils/WarpXUtil.H" -#include "WarpX.H" + +#include <ablastr/warn_manager/WarnManager.H> #include <AMReX.H> #include <AMReX_BLassert.H> @@ -38,7 +39,7 @@ LevelingThinning::LevelingThinning (const std::string species_name) "Resampling target ratio should be strictly greater than 0"); if (m_target_ratio <= 1._rt) { - WarpX::GetInstance().RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "For species '" + species_name + "' " + "target ratio for leveling thinning is smaller or equal to one." + "It is possible that no particle will be removed during resampling"); diff --git a/Source/Python/WarpXWrappers.cpp b/Source/Python/WarpXWrappers.cpp index 399597f60..ec15a67bf 100644 --- a/Source/Python/WarpXWrappers.cpp +++ b/Source/Python/WarpXWrappers.cpp @@ -17,6 +17,8 @@ #include "WarpXWrappers.H" #include "WarpX_py.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX.H> #include <AMReX_ArrayOfStructs.H> #include <AMReX_Box.H> @@ -611,8 +613,9 @@ namespace auto * rho_fp = warpx.get_pointer_rho_fp(lev); if (rho_fp == nullptr) { - warpx.RecordWarning( - "WarpXWrappers", "rho_fp is not allocated", WarnPriority::low + ablastr::warn_manager::WMRecordWarning( + "WarpXWrappers", "rho_fp is not allocated", + ablastr::warn_manager::WarnPriority::low ); return; } diff --git a/Source/Utils/CMakeLists.txt b/Source/Utils/CMakeLists.txt index 4121ee84a..b2754cdaf 100644 --- a/Source/Utils/CMakeLists.txt +++ b/Source/Utils/CMakeLists.txt @@ -7,7 +7,6 @@ target_sources(WarpX MPIInitHelpers.cpp ParticleUtils.cpp RelativeCellPosition.cpp - WarnManager.cpp WarpXAlgorithmSelection.cpp WarpXMovingWindow.cpp WarpXTagging.cpp diff --git a/Source/Utils/MPIInitHelpers.cpp b/Source/Utils/MPIInitHelpers.cpp index 4dc5b9ae8..374165296 100644 --- a/Source/Utils/MPIInitHelpers.cpp +++ b/Source/Utils/MPIInitHelpers.cpp @@ -6,7 +6,7 @@ */ #include "MPIInitHelpers.H" -#include "WarpX.H" +#include <ablastr/warn_manager/WarnManager.H> #include <AMReX_Config.H> #include <AMReX_ParallelDescriptor.H> @@ -66,14 +66,16 @@ namespace utils << mtn(thread_provided) << ") is LOWER than requested " << mtn(thread_required) << "). This might lead to undefined " << "results in asynchronous operations (e.g. async_io)."; - WarpX::GetInstance().RecordWarning("MPI", ss.str(), WarnPriority::high); + ablastr::warn_manager::WMRecordWarning( + "MPI", ss.str(), ablastr::warn_manager::WarnPriority::high); } if( thread_provided > thread_required ){ ss << "NOTE: Provided MPI thread safety level (" << mtn(thread_provided) << ") is stricter than requested " << mtn(thread_required) << "). This might reduce multi-node " << "communication performance."; - WarpX::GetInstance().RecordWarning("MPI", ss.str()); + ablastr::warn_manager::WMRecordWarning( + "MPI", ss.str()); } #endif } diff --git a/Source/Utils/Make.package b/Source/Utils/Make.package index bdd4b61b9..c37715083 100644 --- a/Source/Utils/Make.package +++ b/Source/Utils/Make.package @@ -8,7 +8,6 @@ CEXE_sources += CoarsenMR.cpp CEXE_sources += Interpolate.cpp CEXE_sources += IntervalsParser.cpp CEXE_sources += MPIInitHelpers.cpp -CEXE_sources += WarnManager.cpp CEXE_sources += RelativeCellPosition.cpp CEXE_sources += ParticleUtils.cpp diff --git a/Source/Utils/WarnManager_fwd.H b/Source/Utils/WarnManager_fwd.H deleted file mode 100644 index e12cf7910..000000000 --- a/Source/Utils/WarnManager_fwd.H +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright 2021 Luca Fedeli - * - * This file is part of WarpX. - * - * License: BSD-3-Clause-LBNL - */ - -#ifndef WARPX_WARN_MANAGER_FWD_H -#define WARPX_WARN_MANAGER_FWD_H - -namespace Utils -{ - class WarnManager; -} - -#endif //WARPX_WARN_MANAGER_FWD_H diff --git a/Source/WarpX.H b/Source/WarpX.H index 7f4787db1..6a19169c3 100644 --- a/Source/WarpX.H +++ b/Source/WarpX.H @@ -23,7 +23,6 @@ #include "Particles/ParticleBoundaryBuffer_fwd.H" #include "Particles/MultiParticleContainer_fwd.H" #include "Particles/WarpXParticleContainer_fwd.H" -#include "Utils/WarnManager_fwd.H" #ifdef WARPX_USE_PSATD # ifdef WARPX_DIM_RZ # include "FieldSolver/SpectralSolver/SpectralSolverRZ_fwd.H" @@ -73,27 +72,6 @@ enum struct PatchType : int coarse }; -/** WarnPriority is recorded together with warning messages. It influences - * the display order and the appearance of a warning message. - * This enum class mirrors Utils::MsgLogger::Priority. -*/ -enum class WarnPriority -{ - /** Low priority warning: - * essentially an informative message - */ - low, - /** Medium priority warning: - * a bug or a performance issue may affect the simulation - */ - medium, - /** High priority warning: - * a very serious bug or performance issue - * almost certainly affects the simulation - */ - high -}; - class WarpX : public amrex::AmrCore { @@ -112,35 +90,6 @@ public: int Verbose () const { return verbose; } - /** - * \brief This function records a warning message. - * RecordWarning is thread safe: it can be used within OpenMP parallel loops. - * - * @param[in] topic a string to identify the topic of the warning (e.g., "parallelization", "pbc", "particles"...) - * @param[in] text the text of the warning message - * @param[in] priority priority of the warning message ("medium" by default) - */ - void RecordWarning( - const std::string& topic, - const std::string& text, - const WarnPriority& priority = WarnPriority::medium); - - /** - * \brief This function prints all the warning messages collected on the present MPI rank - * (i.e., this is not a collective call). This function is mainly intended for debug purposes. - * - * @param[in] when a string to mark when the warnings are printed out (it appears in the warning list) - */ - void PrintLocalWarnings(const std::string& when); - - /** - * \brief This function prints all the warning messages collected by all the MPI ranks - * (i.e., this is a collective call). Only the I/O rank prints the message. - * - * @param[in] when a string to mark when the warnings are printed out (it appears in the warning list) - */ - void PrintGlobalWarnings(const std::string& when); - void InitData (); void Evolve (int numsteps = -1); @@ -1154,13 +1103,6 @@ private: # endif #endif - // Warning manager: it allows recording and printing error messages - std::unique_ptr<Utils::WarnManager> m_p_warn_manager; - // Flag to control if WarpX has to emit a warning message as soon as a warning is recorded - bool m_always_warn_immediately = false; - // Threshold to abort immediately on a warning message - std::optional<WarnPriority> m_abort_on_warning_threshold = std::nullopt; - amrex::Vector<int> istep; // which step? amrex::Vector<int> nsubsteps; // how many substeps on each level? diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp index a7d586711..0333d5624 100644 --- a/Source/WarpX.cpp +++ b/Source/WarpX.cpp @@ -32,14 +32,13 @@ #include "Particles/MultiParticleContainer.H" #include "Particles/ParticleBoundaryBuffer.H" #include "Utils/TextMsg.H" -#include "Utils/WarnManager.H" #include "Utils/WarpXAlgorithmSelection.H" #include "Utils/WarpXConst.H" #include "Utils/WarpXProfilerWrapper.H" #include "Utils/WarpXUtil.H" #include <ablastr/utils/SignalHandling.H> -#include <ablastr/utils/msg_logger/MsgLogger.H> +#include <ablastr/warn_manager/WarnManager.H> #ifdef AMREX_USE_SENSEI_INSITU # include <AMReX_AmrMeshInSituBridge.H> @@ -76,14 +75,13 @@ #include <algorithm> #include <cmath> #include <limits> +#include <optional> #include <random> #include <string> #include <utility> using namespace amrex; -namespace abl_msg_logger = ablastr::utils::msg_logger; - Vector<Real> WarpX::E_external_grid(3, 0.0); Vector<Real> WarpX::B_external_grid(3, 0.0); @@ -230,8 +228,6 @@ WarpX::WarpX () { m_instance = this; - m_p_warn_manager = std::make_unique<Utils::WarnManager>(); - ReadParameters(); BackwardCompatibility(); @@ -440,72 +436,6 @@ WarpX::~WarpX () } void -WarpX::RecordWarning( - const std::string& topic, - const std::string& text, - const WarnPriority& priority) -{ - WARPX_PROFILE("WarpX::RecordWarning"); - - auto msg_priority = abl_msg_logger::Priority::high; - if(priority == WarnPriority::low) - msg_priority = abl_msg_logger::Priority::low; - else if(priority == WarnPriority::medium) - msg_priority = abl_msg_logger::Priority::medium; - - if(m_always_warn_immediately){ - - amrex::Warning( - Utils::TextMsg::Warn( - "[" - + std::string(abl_msg_logger::PriorityToString(msg_priority)) - + "][" - + topic - + "] " - + text)); - } - -#ifdef AMREX_USE_OMP - #pragma omp critical -#endif - { - m_p_warn_manager->record_warning(topic, text, msg_priority); - } - - if(m_abort_on_warning_threshold){ - - auto abort_priority = abl_msg_logger::Priority::high; - if(m_abort_on_warning_threshold == WarnPriority::low) - abort_priority = abl_msg_logger::Priority::low; - else if(m_abort_on_warning_threshold == WarnPriority::medium) - abort_priority = abl_msg_logger::Priority::medium; - - WARPX_ALWAYS_ASSERT_WITH_MESSAGE( - msg_priority < abort_priority, - "A warning with priority '" - + abl_msg_logger::PriorityToString(msg_priority) - + "' has been raised." - ); - } -} - -void -WarpX::PrintLocalWarnings(const std::string& when) -{ - WARPX_PROFILE("WarpX::PrintLocalWarnings"); - const std::string warn_string = m_p_warn_manager->print_local_warnings(when); - amrex::AllPrint() << warn_string; -} - -void -WarpX::PrintGlobalWarnings(const std::string& when) -{ - WARPX_PROFILE("WarpX::PrintGlobalWarnings"); - const std::string warn_string = m_p_warn_manager->print_global_warnings(when); - amrex::Print() << warn_string; -} - -void WarpX::ReadParameters () { // Ensure that geometry.dims is set properly. @@ -534,24 +464,28 @@ WarpX::ReadParameters () //"Synthetic" warning messages may be injected in the Warning Manager via // inputfile for debug&testing purposes. - m_p_warn_manager->debug_read_warnings_from_input(pp_warpx); + ablastr::warn_manager::GetWMInstance().debug_read_warnings_from_input(pp_warpx); // Set the flag to control if WarpX has to emit a warning message as soon as a warning is recorded - pp_warpx.query("always_warn_immediately", m_always_warn_immediately); + bool always_warn_immediately = false; + pp_warpx.query("always_warn_immediately", always_warn_immediately); + ablastr::warn_manager::GetWMInstance().SetAlwaysWarnImmediately(always_warn_immediately); // Set the WarnPriority threshold to decide if WarpX has to abort when a warning is recorded if(std::string str_abort_on_warning_threshold = ""; pp_warpx.query("abort_on_warning_threshold", str_abort_on_warning_threshold)){ + std::optional<ablastr::warn_manager::WarnPriority> abort_on_warning_threshold = std::nullopt; if (str_abort_on_warning_threshold == "high") - m_abort_on_warning_threshold = WarnPriority::high; + abort_on_warning_threshold = ablastr::warn_manager::WarnPriority::high; else if (str_abort_on_warning_threshold == "medium" ) - m_abort_on_warning_threshold = WarnPriority::medium; + abort_on_warning_threshold = ablastr::warn_manager::WarnPriority::medium; else if (str_abort_on_warning_threshold == "low") - m_abort_on_warning_threshold = WarnPriority::low; + abort_on_warning_threshold = ablastr::warn_manager::WarnPriority::low; else { Abort(Utils::TextMsg::Err(str_abort_on_warning_threshold +"is not a valid option for warpx.abort_on_warning_threshold (use: low, medium or high)")); } + ablastr::warn_manager::GetWMInstance().SetAbortThreshold(abort_on_warning_threshold); } std::vector<int> numprocs_in; @@ -809,10 +743,10 @@ WarpX::ReadParameters () #ifdef AMREX_USE_FLOAT if (do_single_precision_comms) { do_single_precision_comms = 0; - this->RecordWarning( + ablastr::warn_manager::WMRecordWarning( "comms", "Overwrote warpx.do_single_precision_comms to be 0, since WarpX was built in single precision.", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); } #endif @@ -1092,7 +1026,7 @@ WarpX::ReadParameters () if ((maxLevel() > 0) && (particle_shape > 1) && (do_pml_j_damping == 1)) { - this->RecordWarning("Particles", + ablastr::warn_manager::WMRecordWarning("Particles", "When algo.particle_shape > 1," "some numerical artifact will be present at the interface between coarse and fine patch." "We recommend setting algo.particle_shape = 1 in order to avoid this issue"); @@ -1563,25 +1497,25 @@ WarpX::BackwardCompatibility () ParmParse pp_particles("particles"); int nspecies; if (pp_particles.query("nspecies", nspecies)){ - this->RecordWarning("Species", + ablastr::warn_manager::WMRecordWarning("Species", "particles.nspecies is ignored. Just use particles.species_names please.", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); } ParmParse pp_collisions("collisions"); int ncollisions; if (pp_collisions.query("ncollisions", ncollisions)){ - this->RecordWarning("Collisions", + ablastr::warn_manager::WMRecordWarning("Collisions", "collisions.ncollisions is ignored. Just use particles.collision_names please.", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); } ParmParse pp_lasers("lasers"); int nlasers; if (pp_lasers.query("nlasers", nlasers)){ - this->RecordWarning("Laser", + ablastr::warn_manager::WMRecordWarning("Laser", "lasers.nlasers is ignored. Just use lasers.names please.", - WarnPriority::low); + ablastr::warn_manager::WarnPriority::low); } } diff --git a/Source/ablastr/CMakeLists.txt b/Source/ablastr/CMakeLists.txt index e6f07f283..e5e6cfdbd 100644 --- a/Source/ablastr/CMakeLists.txt +++ b/Source/ablastr/CMakeLists.txt @@ -1,3 +1,4 @@ #add_subdirectory(particles) #add_subdirectory(profiler) add_subdirectory(utils) +add_subdirectory(warn_manager) diff --git a/Source/ablastr/Make.package b/Source/ablastr/Make.package index 6476e3a35..46b3f1858 100644 --- a/Source/ablastr/Make.package +++ b/Source/ablastr/Make.package @@ -2,5 +2,6 @@ include $(WARPX_HOME)/Source/ablastr/particles/Make.package include $(WARPX_HOME)/Source/ablastr/utils/Make.package +include $(WARPX_HOME)/Source/ablastr/warn_manager/Make.package VPATH_LOCATIONS += $(WARPX_HOME)/Source/ablastr diff --git a/Source/ablastr/warn_manager/CMakeLists.txt b/Source/ablastr/warn_manager/CMakeLists.txt new file mode 100644 index 000000000..4c925208a --- /dev/null +++ b/Source/ablastr/warn_manager/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(ablastr + PRIVATE + WarnManager.cpp +) diff --git a/Source/ablastr/warn_manager/Make.package b/Source/ablastr/warn_manager/Make.package new file mode 100644 index 000000000..7614597cf --- /dev/null +++ b/Source/ablastr/warn_manager/Make.package @@ -0,0 +1,3 @@ +CEXE_sources += WarnManager.cpp + +VPATH_LOCATIONS += $(WARPX_HOME)/Source/ablastr/warn_manager diff --git a/Source/Utils/WarnManager.H b/Source/ablastr/warn_manager/WarnManager.H index 243a00ace..1be28f9cd 100644 --- a/Source/Utils/WarnManager.H +++ b/Source/ablastr/warn_manager/WarnManager.H @@ -1,50 +1,77 @@ -/* Copyright 2021 Luca Fedeli +/* Copyright 2022 Luca Fedeli * * This file is part of WarpX. * * License: BSD-3-Clause-LBNL */ -#ifndef WARPX_WARN_MANAGER_H_ -#define WARPX_WARN_MANAGER_H_ +#ifndef ABLASTR_WARN_MANAGER_H_ +#define ABLASTR_WARN_MANAGER_H_ -#include "WarnManager_fwd.H" - -#include <ablastr/utils/msg_logger/MsgLogger_fwd.H> +#include "ablastr/utils/msg_logger/MsgLogger_fwd.H" #include <AMReX_ParmParse.H> #include <memory> +#include <optional> #include <string> -#include <vector> -namespace Utils +namespace ablastr::warn_manager { + + /** WarnPriority is recorded together with warning messages. It influences + * the display order and the appearance of a warning message. + * This enum class mirrors ablastr::utils::msg_logger::Priority. + */ + enum class WarnPriority + { + /** Low priority warning: + * essentially an informative message + */ + low, + /** Medium priority warning: + * a bug or a performance issue may affect the simulation + */ + medium, + /** High priority warning: + * a very serious bug or performance issue + * almost certainly affects the simulation + */ + high + }; + /** - * The class WarnManager manages warning messages in WarpX, + * The singleton class WarnManager manages warning messages, * providing methods to record warnings, and print warning * lists. */ class WarnManager { - public: + public: /** - * The constructor. + * A singleton class should not be cloneable. */ - WarnManager(); + WarnManager(WarnManager &other) = delete; /** - * \brief This function records a warning message. + * A singleton class should not be assignable. + */ + void operator=(const WarnManager &) = delete; + + static WarnManager& GetInstance(); + + /** + * \brief This function records a warning message (recording a warning message is thread-safe) * * @param[in] topic a string to identify the topic of the warning (e.g., "parallelization", "pbc", "particles"...) * @param[in] text the text of the warning message * @param[in] priority priority of the warning message ("medium" by default) */ - void record_warning( + void RecordWarning( std::string topic, std::string text, - ablastr::utils::msg_logger::Priority priority); + WarnPriority priority = WarnPriority::medium); /** * \brief This function prints all the warning messages collected on the present MPI rank @@ -53,7 +80,7 @@ namespace Utils * @param[in] when a string to mark when the warnings are printed out (it appears in the warning list) * @return a string containing the "local" warning list */ - std::string print_local_warnings( + std::string PrintLocalWarnings( const std::string& when) const; /** @@ -63,10 +90,39 @@ namespace Utils * @param[in] when a string to mark when the warnings are printed out (it appears in the warning list) * @return a string containing the "global" warning list */ - std::string print_global_warnings( + std::string PrintGlobalWarnings( const std::string& when) const; /** + * \brief Setter for the m_always_warn_immediately + * + * @param[in] always_warn_immediately new value of the m_always_warn_immediately flag + */ + void SetAlwaysWarnImmediately(bool always_warn_immediately); + + /** + * \brief Getter for the m_always_warn_immediately + * + * @return the m_always_warn_immediately flag + */ + bool GetAlwaysWarnImmediatelyFlag() const; + + /** + * \brief Setter for the m_abort_on_warning_threshold flag + * (pass std::nullopt in order to never abort) + * + * @param[in] abort_threshold new value of the m_abort_on_warning_threshold flag + */ + void SetAbortThreshold(std::optional<WarnPriority> abort_threshold); + + /** + * \brief Getter for the m_abort_on_warning_threshold flag + * + * @return the m_abort_on_warning_threshold flag + */ + std::optional<WarnPriority> GetAbortThreshold() const; + + /** * \brief This function reads warning messages from the inputfile. It is intended for * debug&testing purposes * @@ -77,7 +133,12 @@ namespace Utils static const int warn_line_size = 80 /*! Maximum line length to be used in formatting warning list*/; static const int warn_tab_size = 5 /*! Tabulation size to be used in formatting warning list*/; - private: + private: + + /** + * The constructor. + */ + WarnManager(); /** * \brief This function generates a string for a single entry of the warning list @@ -87,7 +148,7 @@ namespace Utils * @param[in] msg_with_counter a MessageWithCounter * @return a string containing the warning message */ - std::string print_warn_msg( + std::string PrintWarnMsg( const ablastr::utils::msg_logger::MsgWithCounter& msg_with_counter) const; /** @@ -98,7 +159,7 @@ namespace Utils * @param[in] msg_with_counter_and_ranks a MsgWithCounterAndRanks * @return a string containing the warning message */ - std::string print_warn_msg( + std::string PrintWarnMsg( const ablastr::utils::msg_logger::MsgWithCounterAndRanks& msg_with_counter_and_ranks) const; /** @@ -109,7 +170,7 @@ namespace Utils * @param[in] is_global flag: true if the header is for a global warning list, false otherwise * @return a string containing the header of the warning list */ - static std::string get_header( + static std::string GetHeader( const std::string& when, const int line_size, const bool is_global); @@ -122,14 +183,36 @@ namespace Utils * @param[in] tab_size tabulation size to be used in formatting warning list * @return a string containing the formatted warning message text */ - static std::string msg_formatter( + static std::string MsgFormatter( const std::string& msg, const int line_size, const int tab_size); int m_rank = 0 /*! MPI rank (appears in the warning list)*/; std::unique_ptr<ablastr::utils::msg_logger::Logger> m_p_logger /*! The Logger stores all the warning messages*/; + bool m_always_warn_immediately = false /*! Flag to control if the warning logger has to emit a warning message as soon as a warning is recorded*/; + std::optional<WarnPriority> m_abort_on_warning_threshold = std::nullopt /*! Threshold to abort immediately on a warning message*/; }; + + /** + * \brief Helper function to abbreviate the call to get a WarnManager instance + * + * @return the instance of the WarnManager class + */ + WarnManager& GetWMInstance(); + + /** + * \brief Helper function to abbreviate the call to WarnManager::GetInstance().RecordWarning + * (recording a warning message is thread-safe) + * + * @param[in] topic a string to identify the topic of the warning (e.g., "parallelization", "pbc", "particles"...) + * @param[in] text the text of the warning message + * @param[in] priority priority of the warning message ("medium" by default) + */ + void WMRecordWarning( + std::string topic, + std::string text, + WarnPriority priority = WarnPriority::medium); } -#endif //WARPX_WARN_MANAGER_H_ +#endif //ABLASTR_WARN_MANAGER_H_ diff --git a/Source/Utils/WarnManager.cpp b/Source/ablastr/warn_manager/WarnManager.cpp index 18f065ab7..cd440615d 100644 --- a/Source/Utils/WarnManager.cpp +++ b/Source/ablastr/warn_manager/WarnManager.cpp @@ -1,4 +1,4 @@ -/* Copyright 2021 Luca Fedeli +/* Copyright 2022 Luca Fedeli * * This file is part of WarpX. * @@ -7,34 +7,95 @@ #include "WarnManager.H" -#include "WarpXUtil.H" - -#include <ablastr/utils/TextMsg.H> -#include <ablastr/utils/msg_logger/MsgLogger.H> +#include "ablastr/utils/msg_logger/MsgLogger.H" +#include "ablastr/utils/TextMsg.H" #include <AMReX_ParallelDescriptor.H> #include <algorithm> #include <sstream> -using namespace Utils; - namespace abl_msg_logger = ablastr::utils::msg_logger; +using namespace ablastr::warn_manager; + +namespace +{ + WarnPriority MapPriorityToWarnPriority ( + const abl_msg_logger::Priority& priority) + { + using namespace abl_msg_logger; + if (priority == Priority::low) + return WarnPriority::low; + else if (priority == Priority::medium) + return WarnPriority::medium; + else if (priority == Priority::high) + return WarnPriority::high; + else + ablastr::utils::TextMsg::Err( + "Parsing Priority to WarnPriority has failed"); + + return WarnPriority::high; + } +} + +WarnManager& WarnManager::GetInstance() { + static auto warn_manager = WarnManager{}; + return warn_manager; +} WarnManager::WarnManager(): m_rank{amrex::ParallelDescriptor::MyProc()}, m_p_logger{std::make_unique<abl_msg_logger::Logger>()} {} -void WarnManager::record_warning( +void WarnManager::RecordWarning( std::string topic, std::string text, - abl_msg_logger::Priority priority) + WarnPriority priority) { - m_p_logger->record_msg(abl_msg_logger::Msg{topic, text, priority}); + auto msg_priority = abl_msg_logger::Priority::high; + if(priority == WarnPriority::low) + msg_priority = abl_msg_logger::Priority::low; + else if(priority == WarnPriority::medium) + msg_priority = abl_msg_logger::Priority::medium; + + if(m_always_warn_immediately){ + + amrex::Warning( + ablastr::utils::TextMsg::Warn( + "[" + + std::string(abl_msg_logger::PriorityToString(msg_priority)) + + "][" + + topic + + "] " + + text)); + } + +#ifdef AMREX_USE_OMP + #pragma omp critical +#endif + { + m_p_logger->record_msg(abl_msg_logger::Msg{topic, text, msg_priority}); + } + + if(m_abort_on_warning_threshold){ + + auto abort_priority = abl_msg_logger::Priority::high; + if(m_abort_on_warning_threshold == WarnPriority::low) + abort_priority = abl_msg_logger::Priority::low; + else if(m_abort_on_warning_threshold == WarnPriority::medium) + abort_priority = abl_msg_logger::Priority::medium; + + ABLASTR_ALWAYS_ASSERT_WITH_MESSAGE( + msg_priority < abort_priority, + "A warning with priority '" + + abl_msg_logger::PriorityToString(msg_priority) + + "' has been raised." + ); + } } -std::string WarnManager::print_local_warnings(const std::string& when) const +std::string WarnManager::PrintLocalWarnings(const std::string& when) const { auto all_warnings = m_p_logger->get_msgs_with_counter(); std::sort(all_warnings.begin(), all_warnings.end(), @@ -42,14 +103,14 @@ std::string WarnManager::print_local_warnings(const std::string& when) const std::stringstream ss; - ss << "\n" << WarnManager::get_header(when, warn_line_size, false); + ss << "\n" << WarnManager::GetHeader(when, warn_line_size, false); if(all_warnings.empty()){ ss << "* No recorded warnings.\n"; } else{ for(const auto& warn_msg : all_warnings){ - ss << print_warn_msg(warn_msg); + ss << PrintWarnMsg(warn_msg); ss << "*\n"; } } @@ -59,7 +120,7 @@ std::string WarnManager::print_local_warnings(const std::string& when) const return ss.str(); } -std::string WarnManager::print_global_warnings(const std::string& when) const +std::string WarnManager::PrintGlobalWarnings(const std::string& when) const { auto all_warnings = m_p_logger->collective_gather_msgs_with_counter_and_ranks(); @@ -73,14 +134,14 @@ std::string WarnManager::print_global_warnings(const std::string& when) const std::stringstream ss; - ss << "\n" << WarnManager::get_header(when, warn_line_size, true); + ss << "\n" << WarnManager::GetHeader(when, warn_line_size, true); if(all_warnings.empty()){ ss << "* No recorded warnings.\n"; } else{ for(const auto& warn_msg : all_warnings){ - ss << print_warn_msg(warn_msg); + ss << PrintWarnMsg(warn_msg); ss << "*\n"; } } @@ -90,6 +151,26 @@ std::string WarnManager::print_global_warnings(const std::string& when) const return ss.str(); } +void WarnManager::SetAlwaysWarnImmediately(bool always_warn_immediately) +{ + m_always_warn_immediately = always_warn_immediately; +} + +bool WarnManager::GetAlwaysWarnImmediatelyFlag() const +{ + return m_always_warn_immediately; +} + +void WarnManager::SetAbortThreshold(std::optional<WarnPriority> abort_threshold) +{ + m_abort_on_warning_threshold = abort_threshold; +} + +std::optional<WarnPriority> WarnManager::GetAbortThreshold() const +{ + return m_abort_on_warning_threshold; +} + void WarnManager::debug_read_warnings_from_input(amrex::ParmParse& params) { std::vector<std::string> warnings; @@ -106,27 +187,27 @@ void WarnManager::debug_read_warnings_from_input(amrex::ParmParse& params) std::string spriority; pp_warn.query("priority", spriority); - abl_msg_logger::Priority priority = - abl_msg_logger::StringToPriority(spriority); + const auto wpriority = MapPriorityToWarnPriority( + abl_msg_logger::StringToPriority(spriority)); int all_involved = 0; pp_warn.query("all_involved", all_involved); if(all_involved != 0){ - this->record_warning(topic, msg, priority); + this->RecordWarning(topic, msg, wpriority); } else{ std::vector<int> who_involved; pp_warn.queryarr("who_involved", who_involved); if(std::find (who_involved.begin(), who_involved.end(), m_rank) != who_involved.end()){ - this->record_warning(topic, msg, priority); + this->RecordWarning(topic, msg, wpriority); } } } } -std::string WarnManager::print_warn_msg( +std::string WarnManager::PrintWarnMsg( const abl_msg_logger::MsgWithCounter& msg_with_counter) const { std::stringstream ss; @@ -149,16 +230,16 @@ std::string WarnManager::print_warn_msg( else ss << "[raised " << msg_with_counter.counter << " times]\n"; - ss << msg_formatter(msg_with_counter.msg.text, warn_line_size, warn_tab_size); + ss << MsgFormatter(msg_with_counter.msg.text, warn_line_size, warn_tab_size); return ss.str(); } -std::string WarnManager::print_warn_msg( +std::string WarnManager::PrintWarnMsg( const abl_msg_logger::MsgWithCounterAndRanks& msg_with_counter_and_ranks) const { std::stringstream ss; - ss << this->print_warn_msg(msg_with_counter_and_ranks.msg_with_counter); + ss << this->PrintWarnMsg(msg_with_counter_and_ranks.msg_with_counter); std::string raised_by = "@ Raised by: "; if (!msg_with_counter_and_ranks.all_ranks){ @@ -168,12 +249,12 @@ std::string WarnManager::print_warn_msg( else{ raised_by += "ALL\n"; } - ss << WarnManager::msg_formatter(raised_by, warn_line_size, warn_tab_size); + ss << WarnManager::MsgFormatter(raised_by, warn_line_size, warn_tab_size); return ss.str(); } -std::string WarnManager::get_header( +std::string WarnManager::GetHeader( const std::string& when, const int line_size, const bool is_global) @@ -198,7 +279,7 @@ std::string WarnManager::get_header( } std::string -WarnManager::msg_formatter( +WarnManager::MsgFormatter( const std::string& msg, const int line_size, const int tab_size) @@ -215,3 +296,17 @@ WarnManager::msg_formatter( return ss_out.str(); } + +WarnManager& ablastr::warn_manager::GetWMInstance() +{ + return WarnManager::GetInstance(); +} + +void ablastr::warn_manager::WMRecordWarning( + std::string topic, + std::string text, + WarnPriority priority) +{ + WarnManager::GetInstance().RecordWarning( + topic, text, priority); +} diff --git a/Source/main.cpp b/Source/main.cpp index 5587d4f93..dc1a00e8b 100644 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -13,6 +13,8 @@ #include "Utils/WarpXUtil.H" #include "Utils/WarpXProfilerWrapper.H" +#include <ablastr/warn_manager/WarnManager.H> + #include <AMReX.H> #include <AMReX_Config.H> #include <AMReX_ParallelDescriptor.H> @@ -64,7 +66,8 @@ int main(int argc, char* argv[]) warpx.Evolve(); - warpx.PrintGlobalWarnings("THE END"); //Print warning messages at the end of the simulation + //Print warning messages at the end of the simulation + ablastr::warn_manager::GetWMInstance().PrintGlobalWarnings("THE END"); if (warpx.Verbose()) { auto end_total = static_cast<Real>(amrex::second()) - strt_total; |