diff options
author | 2021-10-20 21:02:22 +0200 | |
---|---|---|
committer | 2021-10-20 19:02:22 +0000 | |
commit | 02096d079680a2f7125db230bcde872dde63732c (patch) | |
tree | 14064a6a0b029a16f77ad357772546334e841867 /Source/Utils/WarnManager.cpp | |
parent | c3f481bca813d834e248d1adeb5b5a02495b9e1a (diff) | |
download | WarpX-02096d079680a2f7125db230bcde872dde63732c.tar.gz WarpX-02096d079680a2f7125db230bcde872dde63732c.tar.zst WarpX-02096d079680a2f7125db230bcde872dde63732c.zip |
⚠️ Add warning logger (#2113)
* improve error msg
* eliminate final dot
* initial layout of the main classes
* progress
* progress with warnings
* print local errors
* progress with warning logger
* improved MsgLogger
* added file to test warnings
* added method to read debug warnings from inputfile
* progress towards collective gather of warnings
* add missing blank line in warning message
* move misplaced file
* refactoring
* fixed bugs
* progress
* fixed bugs
* fixed some bugs
* it finally works!
* add comments in WarpX.H
* add missing comment
* added comments to WarpX.cpp
* add profiler to WarpX.cpp
* expose option to enable 'warn immediately' feature in cmake
* Add comment to main.cpp
* add missing comment in WarpX.cpp
* add copyright and include guards to WarnManager_fwd.H
* cleaning and added comments to WarnManager.H
* updated test
* added fwd file for MsgLogger
* cleaning
* Added copyright in WarnManager.cpp
* Cleaning
* cleaning
* Add missing copyright
* cleaning
* clean and add comments to MsgLoggerSerialization.H
* cleaning MsgLogger_fwd.H
* cleaning
* continue cleaning MsgLogger
* added comments & bugfixing
* removed test file
* fixed bugs
* Update Source/Utils/MsgLogger/MsgLogger.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/WarpX.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/MsgLogger/MsgLogger.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/MsgLogger/MsgLogger.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/MsgLogger/MsgLogger.cpp
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/MsgLogger/MsgLoggerSerialization.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/MsgLogger/MsgLoggerSerialization.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/MsgLogger/MsgLoggerSerialization.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/MsgLogger/MsgLoggerSerialization.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/MsgLogger/MsgLoggerSerialization.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/WarnManager.cpp
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/WarnManager.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/WarnManager.H
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Update Source/Utils/WarnManager.cpp
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* fixed bugs
* Update Source/Utils/MsgLogger/MsgLogger.cpp
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
* Added comment to explain rotation
* use last value computed by partial_sum
* fix bug
* now use error stream
* using anonymous namespace for helper functions
* print on both stderr and stdout
* now using runtime parameter to always print warnings
* added documentation
* using long int for counter
* sort affected warnings list
* add doc entry
* removed doc
* added documentation
* fixed bug
* fixed bug
* removing unnecessary text
* reformatting
* reformatting
* fixed bug
* fixed bug
* correction
* add warning_logger.rst to toctree in developers.rst
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
Diffstat (limited to 'Source/Utils/WarnManager.cpp')
-rw-r--r-- | Source/Utils/WarnManager.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/Source/Utils/WarnManager.cpp b/Source/Utils/WarnManager.cpp new file mode 100644 index 000000000..c3b8d3159 --- /dev/null +++ b/Source/Utils/WarnManager.cpp @@ -0,0 +1,239 @@ +/* Copyright 2021 Luca Fedeli + * + * This file is part of WarpX. + * + * License: BSD-3-Clause-LBNL + */ + +#include "WarnManager.H" + +#include "MsgLogger/MsgLogger.H" + +#include <AMReX_ParallelDescriptor.H> + +#include <algorithm> +#include <sstream> + +using namespace Utils; +using namespace Utils::MsgLogger; + +WarnManager::WarnManager(){ + m_rank = amrex::ParallelDescriptor::MyProc(); + m_p_logger = std::make_unique<Logger>(); +} + +void WarnManager::record_warning( + std::string topic, + std::string text, + Priority priority) +{ + m_p_logger->record_msg(Msg{topic, text, priority}); +} + +std::string WarnManager::print_local_warnings(const std::string& when) const +{ + auto all_warnings = m_p_logger->get_msgs_with_counter(); + std::sort(all_warnings.begin(), all_warnings.end(), + [](const auto& a, const auto& b){return a.msg < b.msg;}); + + std::stringstream ss; + + ss << "\n" << get_header(when, warn_line_size, false); + + if(all_warnings.size() == 0){ + ss << "* No recorded warnings.\n"; + } + else{ + for(const auto& warn_msg : all_warnings){ + ss << print_warn_msg(warn_msg); + ss << "*\n"; + } + } + + ss << std::string(warn_line_size, '*') << "\n\n" ; + + return ss.str(); +} + +std::string WarnManager::print_global_warnings(const std::string& when) const +{ + auto all_warnings = + m_p_logger->collective_gather_msgs_with_counter_and_ranks(); + + if(m_rank != amrex::ParallelDescriptor::IOProcessorNumber()) + return "[see I/O rank message]"; + + std::sort(all_warnings.begin(), all_warnings.end(), + [](const auto& a, const auto& b){ + return a.msg_with_counter.msg < b.msg_with_counter.msg;}); + + std::stringstream ss; + + ss << "\n" << get_header(when, warn_line_size, true); + + if(all_warnings.size() == 0){ + ss << "* No recorded warnings.\n"; + } + else{ + for(const auto& warn_msg : all_warnings){ + ss << print_warn_msg(warn_msg); + ss << "*\n"; + } + } + + ss << std::string(warn_line_size, '*') << "\n\n" ; + + return ss.str(); +} + +void WarnManager::debug_read_warnings_from_input(amrex::ParmParse& params) +{ + std::vector<std::string> warnings; + params.queryarr("test_warnings", warnings); + + for (const auto& warn : warnings){ + amrex::ParmParse pp_warn(warn); + + std::string topic; + pp_warn.query("topic", topic); + + std::string msg; + pp_warn.query("msg", msg); + + std::string spriority; + pp_warn.query("priority", spriority); + Priority priority = StringToPriority(spriority); + + int all_involved = 0; + pp_warn.query("all_involved", all_involved); + if(all_involved){ + this->record_warning(topic, msg, priority); + } + 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); + } + } + } + +} + +std::string WarnManager::get_header( + const std::string& when, + const int line_size, + const bool is_global) const +{ + const std::string warn_header{"**** WARNINGS "}; + + std::stringstream ss; + + ss << warn_header << + std::string(line_size - static_cast<int>(warn_header.length()), '*') << "\n" ; + + if(is_global){ + ss << "* GLOBAL warning list after " << " [ " << when << " ]\n*\n"; + } + else{ + auto const mpi_rank = amrex::ParallelDescriptor::MyProc(); + ss << "* LOCAL" << " ( rank # " << mpi_rank << " ) " + << " warning list after " << when << "\n*\n"; + } + + return ss.str(); +} + +std::string WarnManager::print_warn_msg( + const MsgLogger::MsgWithCounter& msg_with_counter) const +{ + std::stringstream ss; + ss << "* --> "; + if (msg_with_counter.msg.priority == MsgLogger::Priority::high) + ss << "[!!!]"; + else if (msg_with_counter.msg.priority == MsgLogger::Priority::medium) + ss << "[!! ]"; + else if (msg_with_counter.msg.priority == MsgLogger::Priority::low) + ss << "[! ]"; + else + ss << "[???]"; + + ss << " [" + msg_with_counter.msg.topic << "] "; + + if(msg_with_counter.counter == 2) + ss << "[raised twice]\n"; + else if(msg_with_counter.counter == 1) + ss << "[raised once]\n"; + else + ss << "[raised " << msg_with_counter.counter << " times]\n"; + + ss << msg_formatter(msg_with_counter.msg.text, warn_line_size, warn_tab_size); + + return ss.str(); +} + +std::string WarnManager::print_warn_msg( + const MsgLogger::MsgWithCounterAndRanks& msg_with_counter_and_ranks) const +{ + std::stringstream ss; + ss << this->print_warn_msg(msg_with_counter_and_ranks.msg_with_counter); + + std::string raised_by = "@ Raised by: "; + if (!msg_with_counter_and_ranks.all_ranks){ + for (const auto rr : msg_with_counter_and_ranks.ranks) + raised_by += " " + std::to_string(rr); + } + else{ + raised_by += "ALL\n"; + } + ss << msg_formatter(raised_by, warn_line_size, warn_tab_size); + + return ss.str(); +} + +std::string +WarnManager::msg_formatter( + const std::string& msg, + const int line_size, + const int tab_size) const +{ + const auto prefix = "*" + std::string(tab_size, ' '); + const auto prefix_length = static_cast<int>(prefix.length()); + + std::stringstream ss_out; + std::stringstream ss_msg{msg}; + + std::string line; + std::string word; + + while(std::getline(ss_msg, line,'\n')){ + ss_out << prefix; + + std::stringstream ss_line{line}; + int counter = prefix_length; + + while (ss_line >> word){ + const auto wlen = static_cast<int>(word.length()); + + if(counter == prefix_length){ + ss_out << word; + counter += wlen; + } + else{ + if (counter + wlen < line_size){ + ss_out << " " << word; + counter += (wlen+1); + } + else{ + ss_out << "\n" << prefix << word; + counter = prefix_length + wlen; + } + } + } + + ss_out << '\n'; + } + + return ss_out.str(); +} |