Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <iomanip> 7 : #include <ios> 8 : #include <limits> 9 : #include <sstream> 10 : 11 : #include "DataStructures/DataBox/DataBox.hpp" 12 : #include "Parallel/GlobalCache.hpp" 13 : #include "Parallel/Printf/Printf.hpp" 14 : #include "ParallelAlgorithms/Interpolation/InterpolatedVars.hpp" 15 : #include "ParallelAlgorithms/Interpolation/Tags.hpp" 16 : #include "Utilities/FileSystem.hpp" 17 : #include "Utilities/PrettyType.hpp" 18 : #include "Utilities/TMPL.hpp" 19 : 20 : namespace deadlock { 21 : /*! 22 : * \brief Simple action to print information from the Interpolator. 23 : * 24 : * \details Makes a directory called `interpolator` inside the \p deadlock_dir 25 : * if it doesn't exist. Then writes to a new file for each target the following 26 : * information only for sequential targets for all temporal ids stored: 27 : * 28 : * - Interpolator core 29 : * - Temporal id 30 : * - Iteration number 31 : * - Expected number of elements to receive 32 : * - Current number of elements received 33 : * - Missing elements 34 : */ 35 1 : struct PrintInterpolator { 36 : template <typename ParallelComponent, typename DbTags, typename Metavariables, 37 : typename ArrayIndex> 38 0 : static void apply(const db::DataBox<DbTags>& box, 39 : const Parallel::GlobalCache<Metavariables>& cache, 40 : const ArrayIndex& array_index, 41 : const std::string& deadlock_dir) { 42 : using target_tags = typename Metavariables::interpolation_target_tags; 43 : 44 : const std::string intrp_deadlock_dir = deadlock_dir + "/interpolator"; 45 : if (not file_system::check_if_dir_exists(intrp_deadlock_dir)) { 46 : file_system::create_directory(intrp_deadlock_dir); 47 : } 48 : 49 : tmpl::for_each<target_tags>([&](const auto tag_v) { 50 : using target_tag = tmpl::type_from<decltype(tag_v)>; 51 : const std::string& target_name = pretty_type::name<target_tag>(); 52 : 53 : // Only need to print the sequential targets (aka horizons) 54 : if constexpr (target_tag::compute_target_points::is_sequential::value) { 55 : const std::string file_name = 56 : intrp_deadlock_dir + "/" + target_name + ".out"; 57 : 58 : const auto& holders = 59 : db::get<intrp::Tags::InterpolatedVarsHolders<Metavariables>>(box); 60 : const auto& vars_infos = 61 : get<intrp::Vars::HolderTag<target_tag, Metavariables>>(holders) 62 : .infos; 63 : const auto& num_elements = 64 : db::get<intrp::Tags::NumberOfElements<Metavariables::volume_dim>>( 65 : box); 66 : 67 : if (vars_infos.empty()) { 68 : Parallel::fprintf(file_name, "No data on interpolator core %zu\n", 69 : array_index); 70 : return; 71 : } 72 : 73 : std::stringstream ss{}; 74 : ss << std::setprecision(std::numeric_limits<double>::digits10 + 4) 75 : << std::scientific; 76 : 77 : ss << "========== BEGIN INTERPOLATOR CORE " << array_index 78 : << " ==========\n"; 79 : 80 : for (const auto& [temporal_id, info] : vars_infos) { 81 : ss << "Temporal id " << temporal_id << ": " 82 : << "Iteration " << info.iteration << ", expecting data from " 83 : << num_elements.at(target_name).size() 84 : << " elements, but only received " 85 : << info.interpolation_is_done_for_these_elements.size() 86 : << ". Missing these elements: "; 87 : 88 : std::unordered_set<ElementId<Metavariables::volume_dim>> difference{}; 89 : for (const auto& element : num_elements.at(target_name)) { 90 : if (not info.interpolation_is_done_for_these_elements.contains( 91 : element)) { 92 : difference.insert(element); 93 : } 94 : } 95 : 96 : ss << difference << "\n"; 97 : } 98 : 99 : ss << "========== END INTERPOLATOR CORE " << array_index 100 : << " ============\n"; 101 : 102 : Parallel::fprintf(file_name, "%s\n", ss.str()); 103 : } 104 : }); 105 : 106 : (void)box; 107 : (void)cache; 108 : (void)array_index; 109 : } 110 : }; 111 : } // namespace deadlock