-----------------------------------------------------------------------------
| 67 | } |
| 68 | //----------------------------------------------------------------------------- |
| 69 | Table Table::reduce(MPI_Comm comm, Table::Reduction reduction) const |
| 70 | { |
| 71 | std::string new_title; |
| 72 | |
| 73 | // Prepare reduction operation y := op(y, x) |
| 74 | std::function<double(double, double)> op_impl; |
| 75 | switch (reduction) |
| 76 | { |
| 77 | case Table::Reduction::average: |
| 78 | new_title = "[MPI_AVG] "; |
| 79 | op_impl = [](double y, double x) { return y + x; }; |
| 80 | break; |
| 81 | case Table::Reduction::min: |
| 82 | new_title = "[MPI_MIN] "; |
| 83 | op_impl = [](double y, double x) { return std::min(y, x); }; |
| 84 | break; |
| 85 | case Table::Reduction::max: |
| 86 | new_title = "[MPI_MAX] "; |
| 87 | op_impl = [](double y, double x) { return std::max(y, x); }; |
| 88 | break; |
| 89 | default: |
| 90 | throw std::runtime_error("Cannot perform reduction of Table. Requested " |
| 91 | "reduction not implemented"); |
| 92 | } |
| 93 | new_title += name; |
| 94 | |
| 95 | const int mpi_size = dolfinx::MPI::size(comm); |
| 96 | |
| 97 | // Handle trivial reduction |
| 98 | if (mpi_size == 1) |
| 99 | { |
| 100 | Table table_all(*this); |
| 101 | table_all.name = new_title; |
| 102 | return table_all; |
| 103 | } |
| 104 | |
| 105 | // Get keys, values into containers for int doubles |
| 106 | std::string keys; |
| 107 | std::vector<double> values; |
| 108 | for (auto& it : _values) |
| 109 | { |
| 110 | if (const auto* const pval = std::get_if<double>(&it.second)) |
| 111 | { |
| 112 | keys += it.first.first + '\0' + it.first.second + '\0'; |
| 113 | values.push_back(*pval); |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | // Gather to rank zero |
| 118 | |
| 119 | // Get string data size on each process |
| 120 | std::vector<int> pcounts(mpi_size), offsets(mpi_size + 1, 0); |
| 121 | const int local_size_str = keys.size(); |
| 122 | int err = MPI_Gather(&local_size_str, 1, MPI_INT, pcounts.data(), 1, MPI_INT, |
| 123 | 0, comm); |
| 124 | dolfinx::MPI::check_error(comm, err); |
| 125 | std::partial_sum(pcounts.begin(), pcounts.end(), offsets.begin() + 1); |
| 126 | std::vector<char> out_str(offsets.back()); |
no test coverage detected