| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "alekseev_a_global_opt_chars/mpi/include/ops_mpi.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cmath> | ||
| 7 | #include <cstddef> | ||
| 8 | #include <limits> | ||
| 9 | #include <utility> | ||
| 10 | #include <vector> | ||
| 11 | |||
| 12 | #include "alekseev_a_global_opt_chars/common/include/common.hpp" | ||
| 13 | |||
| 14 | namespace alekseev_a_global_opt_chars { | ||
| 15 | |||
| 16 | namespace { | ||
| 17 | |||
| 18 | 140 | void ComputeDistribution(int num_items, int world_size, std::vector<int> &counts, std::vector<int> &displs) { | |
| 19 | 140 | counts.assign(static_cast<std::size_t>(world_size), 0); | |
| 20 | 140 | displs.assign(static_cast<std::size_t>(world_size), 0); | |
| 21 | |||
| 22 | 140 | const int base = num_items / world_size; | |
| 23 | 140 | const int rem = num_items % world_size; | |
| 24 | |||
| 25 |
2/2✓ Branch 0 taken 280 times.
✓ Branch 1 taken 140 times.
|
420 | for (int i = 0; i < world_size; ++i) { |
| 26 |
4/4✓ Branch 0 taken 208 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 140 times.
✓ Branch 3 taken 140 times.
|
488 | counts[static_cast<std::size_t>(i)] = base + ((i < rem) ? 1 : 0); |
| 27 | 280 | displs[static_cast<std::size_t>(i)] = | |
| 28 |
2/2✓ Branch 0 taken 140 times.
✓ Branch 1 taken 140 times.
|
280 | (i == 0) ? 0 : (displs[static_cast<std::size_t>(i - 1)] + counts[static_cast<std::size_t>(i - 1)]); |
| 29 | } | ||
| 30 | 140 | } | |
| 31 | |||
| 32 | 70 | void PackIntervalsData(const std::vector<double> &t_points, const std::vector<TrialPoint> &trial_points, | |
| 33 | int interval_count, std::vector<double> &packed) { | ||
| 34 | 70 | packed.resize(static_cast<std::size_t>(interval_count) * 4); | |
| 35 | |||
| 36 |
2/2✓ Branch 0 taken 464 times.
✓ Branch 1 taken 70 times.
|
534 | for (int i = 0; i < interval_count; ++i) { |
| 37 | 464 | const auto idx = static_cast<std::size_t>(i); | |
| 38 | 464 | packed[(idx * 4) + 0] = t_points[idx]; | |
| 39 | 464 | packed[(idx * 4) + 1] = t_points[idx + 1]; | |
| 40 | 464 | packed[(idx * 4) + 2] = trial_points[idx].z; | |
| 41 | 464 | packed[(idx * 4) + 3] = trial_points[idx + 1].z; | |
| 42 | } | ||
| 43 | 70 | } | |
| 44 | |||
| 45 | 140 | void ComputeLocalCharacteristics(const std::vector<double> &local_interval_data, int local_interval_count, double m_val, | |
| 46 | std::vector<double> &local_chars) { | ||
| 47 | 140 | local_chars.resize(static_cast<std::size_t>(local_interval_count)); | |
| 48 | |||
| 49 |
2/2✓ Branch 0 taken 464 times.
✓ Branch 1 taken 140 times.
|
604 | for (int i = 0; i < local_interval_count; ++i) { |
| 50 | 464 | const auto idx = static_cast<std::size_t>(i); | |
| 51 | |||
| 52 | 464 | const double t_left = local_interval_data[(idx * 4) + 0]; | |
| 53 | 464 | const double t_right = local_interval_data[(idx * 4) + 1]; | |
| 54 | 464 | const double z_left = local_interval_data[(idx * 4) + 2]; | |
| 55 | 464 | const double z_right = local_interval_data[(idx * 4) + 3]; | |
| 56 | |||
| 57 | 464 | const double dt = t_right - t_left; | |
| 58 | 464 | const double dz = z_right - z_left; | |
| 59 | |||
| 60 | 464 | local_chars[idx] = (m_val * dt) + ((dz * dz) / (m_val * dt)) - (2.0 * (z_right + z_left)); | |
| 61 | } | ||
| 62 | 140 | } | |
| 63 | |||
| 64 | 140 | void GatherCharacteristicsToRoot(const std::vector<double> &local_chars, const std::vector<int> &counts, | |
| 65 | const std::vector<int> &displs, int world_rank, int world_size, | ||
| 66 | std::vector<double> &all_chars) { | ||
| 67 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
|
140 | const int local_count = counts[static_cast<std::size_t>(world_rank)]; |
| 68 | |||
| 69 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
|
140 | if (world_rank == 0) { |
| 70 |
2/2✓ Branch 0 taken 250 times.
✓ Branch 1 taken 70 times.
|
320 | for (int i = 0; i < counts[0]; ++i) { |
| 71 | 250 | all_chars[static_cast<std::size_t>(i)] = local_chars[static_cast<std::size_t>(i)]; | |
| 72 | } | ||
| 73 | |||
| 74 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
|
140 | for (int proc = 1; proc < world_size; ++proc) { |
| 75 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 64 times.
|
70 | const int proc_count = counts[static_cast<std::size_t>(proc)]; |
| 76 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 64 times.
|
70 | if (proc_count <= 0) { |
| 77 | 6 | continue; | |
| 78 | } | ||
| 79 | |||
| 80 |
1/2✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
|
64 | std::vector<double> recv(proc_count); |
| 81 |
1/2✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
|
64 | MPI_Recv(recv.data(), proc_count, MPI_DOUBLE, proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); |
| 82 | |||
| 83 | 64 | const int disp = displs[static_cast<std::size_t>(proc)]; | |
| 84 |
2/2✓ Branch 0 taken 214 times.
✓ Branch 1 taken 64 times.
|
278 | for (int i = 0; i < proc_count; ++i) { |
| 85 | 214 | all_chars[static_cast<std::size_t>(disp) + i] = recv[static_cast<std::size_t>(i)]; | |
| 86 | } | ||
| 87 | } | ||
| 88 | } else { | ||
| 89 |
2/2✓ Branch 0 taken 64 times.
✓ Branch 1 taken 6 times.
|
70 | if (local_count > 0) { |
| 90 | 64 | MPI_Send(local_chars.data(), local_count, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); | |
| 91 | } | ||
| 92 | } | ||
| 93 | 140 | } | |
| 94 | |||
| 95 | } // namespace | ||
| 96 | |||
| 97 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | AlekseevAGlobalOptCharsMPI::AlekseevAGlobalOptCharsMPI(const InType &in) { |
| 98 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 99 | GetInput() = in; | ||
| 100 | 12 | GetOutput() = OutType(); | |
| 101 | |||
| 102 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | MPI_Comm_rank(MPI_COMM_WORLD, &world_rank_); |
| 103 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | MPI_Comm_size(MPI_COMM_WORLD, &world_size_); |
| 104 | 12 | } | |
| 105 | |||
| 106 | 12 | bool AlekseevAGlobalOptCharsMPI::ValidationImpl() { | |
| 107 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
|
12 | if (world_rank_ != 0) { |
| 108 | return true; | ||
| 109 | } | ||
| 110 | |||
| 111 | const auto &input = GetInput(); | ||
| 112 | |||
| 113 | bool valid = true; | ||
| 114 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | valid = valid && (input.func != nullptr); |
| 115 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | valid = valid && (input.x_min < input.x_max); |
| 116 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | valid = valid && (input.y_min < input.y_max); |
| 117 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | valid = valid && (input.epsilon > 0.0); |
| 118 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | valid = valid && (input.r_param > 1.0); |
| 119 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | valid = valid && (input.max_iterations > 0); |
| 120 | |||
| 121 | return valid; | ||
| 122 | } | ||
| 123 | |||
| 124 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | bool AlekseevAGlobalOptCharsMPI::PreProcessingImpl() { |
| 125 | trial_points_.clear(); | ||
| 126 | t_points_.clear(); | ||
| 127 | 12 | lipschitz_estimate_ = 1.0; | |
| 128 | 12 | return true; | |
| 129 | } | ||
| 130 | |||
| 131 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | bool AlekseevAGlobalOptCharsMPI::RunImpl() { |
| 132 | const auto &input = GetInput(); | ||
| 133 | auto &output = GetOutput(); | ||
| 134 | |||
| 135 | trial_points_.clear(); | ||
| 136 | t_points_.clear(); | ||
| 137 | |||
| 138 | 12 | std::vector<double> init_pack(8, 0.0); | |
| 139 | |||
| 140 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
|
12 | if (world_rank_ == 0) { |
| 141 | const double t0 = 0.0; | ||
| 142 | const double t1 = 1.0; | ||
| 143 | |||
| 144 | 6 | const double x0 = PeanoToX(t0, input.x_min, input.x_max, peano_level_); | |
| 145 | 6 | const double y0 = PeanoToY(t0, input.y_min, input.y_max, peano_level_); | |
| 146 | 6 | const double z0 = input.func(x0, y0); | |
| 147 | |||
| 148 | 6 | const double x1 = PeanoToX(t1, input.x_min, input.x_max, peano_level_); | |
| 149 | 6 | const double y1 = PeanoToY(t1, input.y_min, input.y_max, peano_level_); | |
| 150 | 6 | const double z1 = input.func(x1, y1); | |
| 151 | |||
| 152 | 6 | init_pack[0] = t0; | |
| 153 | 6 | init_pack[1] = x0; | |
| 154 | 6 | init_pack[2] = y0; | |
| 155 | 6 | init_pack[3] = z0; | |
| 156 | 6 | init_pack[4] = t1; | |
| 157 | 6 | init_pack[5] = x1; | |
| 158 | 6 | init_pack[6] = y1; | |
| 159 | 6 | init_pack[7] = z1; | |
| 160 | } | ||
| 161 | |||
| 162 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | MPI_Bcast(init_pack.data(), 8, MPI_DOUBLE, 0, MPI_COMM_WORLD); |
| 163 | |||
| 164 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | t_points_.push_back(init_pack[0]); |
| 165 | t_points_.push_back(init_pack[4]); | ||
| 166 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | trial_points_.emplace_back(init_pack[1], init_pack[2], init_pack[3]); |
| 167 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | trial_points_.emplace_back(init_pack[5], init_pack[6], init_pack[7]); |
| 168 | |||
| 169 | 12 | output.iterations = 0; | |
| 170 | 12 | output.converged = false; | |
| 171 | |||
| 172 |
1/2✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
|
140 | for (int iter = 0; iter < input.max_iterations; ++iter) { |
| 173 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | BroadcastTrialData(); |
| 174 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | SortingTrials(); |
| 175 | |||
| 176 | 140 | lipschitz_estimate_ = ComputeLipschitzEstimate(); | |
| 177 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
|
140 | if (lipschitz_estimate_ < 1e-10) { |
| 178 | ✗ | lipschitz_estimate_ = 1.0; | |
| 179 | } | ||
| 180 | |||
| 181 | 140 | const double m_val = input.r_param * lipschitz_estimate_; | |
| 182 | |||
| 183 | 140 | std::vector<double> characteristics; | |
| 184 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | CharacteristicsParallelComputed(m_val, characteristics); |
| 185 | |||
| 186 | const int best_interval_idx = BestInterval(characteristics); | ||
| 187 | |||
| 188 |
2/2✓ Branch 0 taken 128 times.
✓ Branch 1 taken 12 times.
|
140 | const double t_left = t_points_[best_interval_idx]; |
| 189 | 140 | const double t_right = t_points_[best_interval_idx + 1]; | |
| 190 | 140 | const double z_left = trial_points_[best_interval_idx].z; | |
| 191 | 140 | const double z_right = trial_points_[best_interval_idx + 1].z; | |
| 192 | |||
| 193 | 140 | const double interval_len = t_right - t_left; | |
| 194 | |||
| 195 |
2/2✓ Branch 0 taken 128 times.
✓ Branch 1 taken 12 times.
|
140 | int stop_flag = (interval_len < input.epsilon) ? 1 : 0; |
| 196 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | MPI_Bcast(&stop_flag, 1, MPI_INT, 0, MPI_COMM_WORLD); |
| 197 | |||
| 198 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 128 times.
|
140 | if (stop_flag != 0) { |
| 199 | 12 | output.converged = true; | |
| 200 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | output.iterations = iter + 1; |
| 201 | break; | ||
| 202 | } | ||
| 203 | |||
| 204 | 128 | double t_new = (0.5 * (t_left + t_right)) - ((z_right - z_left) / (2.0 * m_val)); | |
| 205 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 128 times.
✗ Branch 3 not taken.
|
128 | t_new = std::max(t_left + 1e-12, std::min(t_new, t_right - 1e-12)); |
| 206 | |||
| 207 |
2/2✓ Branch 0 taken 64 times.
✓ Branch 1 taken 64 times.
|
128 | if (world_rank_ == 0) { |
| 208 |
1/2✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
|
64 | const double z_new = PerformTrial(t_new); |
| 209 | 64 | const double x_new = PeanoToX(t_new, input.x_min, input.x_max, peano_level_); | |
| 210 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
|
64 | const double y_new = PeanoToY(t_new, input.y_min, input.y_max, peano_level_); |
| 211 | |||
| 212 | t_points_.push_back(t_new); | ||
| 213 |
1/2✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
|
64 | trial_points_.emplace_back(x_new, y_new, z_new); |
| 214 | } | ||
| 215 | |||
| 216 |
1/2✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
|
128 | output.iterations = iter + 1; |
| 217 | } | ||
| 218 | |||
| 219 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | BroadcastTrialData(); |
| 220 | |||
| 221 | 12 | return true; | |
| 222 | } | ||
| 223 | |||
| 224 | 12 | bool AlekseevAGlobalOptCharsMPI::PostProcessingImpl() { | |
| 225 | auto &output = GetOutput(); | ||
| 226 | |||
| 227 | double best_z = std::numeric_limits<double>::max(); | ||
| 228 | std::size_t best_idx = 0; | ||
| 229 | |||
| 230 |
2/2✓ Branch 0 taken 152 times.
✓ Branch 1 taken 12 times.
|
164 | for (std::size_t i = 0; i < trial_points_.size(); ++i) { |
| 231 |
2/2✓ Branch 0 taken 52 times.
✓ Branch 1 taken 100 times.
|
152 | if (trial_points_[i].z < best_z) { |
| 232 | best_z = trial_points_[i].z; | ||
| 233 | best_idx = i; | ||
| 234 | } | ||
| 235 | } | ||
| 236 | |||
| 237 | 12 | output.x_opt = trial_points_[best_idx].x; | |
| 238 | 12 | output.y_opt = trial_points_[best_idx].y; | |
| 239 | 12 | output.func_min = best_z; | |
| 240 | |||
| 241 | 12 | return true; | |
| 242 | } | ||
| 243 | |||
| 244 | 140 | void AlekseevAGlobalOptCharsMPI::SortingTrials() { | |
| 245 | 140 | std::vector<std::size_t> idx(t_points_.size()); | |
| 246 |
2/2✓ Branch 0 taken 1068 times.
✓ Branch 1 taken 140 times.
|
1208 | for (std::size_t i = 0; i < idx.size(); ++i) { |
| 247 | 1068 | idx[i] = i; | |
| 248 | } | ||
| 249 | |||
| 250 |
3/22✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 928 times.
✓ Branch 20 taken 470 times.
✓ Branch 21 taken 928 times.
|
2326 | std::ranges::sort(idx, [this](std::size_t a, std::size_t b) { return t_points_[a] < t_points_[b]; }); |
| 251 | |||
| 252 |
2/6✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 140 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
140 | std::vector<double> sorted_t(t_points_.size()); |
| 253 |
1/4✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
140 | std::vector<TrialPoint> sorted_trials(trial_points_.size()); |
| 254 | |||
| 255 |
2/2✓ Branch 0 taken 1068 times.
✓ Branch 1 taken 140 times.
|
1208 | for (std::size_t i = 0; i < idx.size(); ++i) { |
| 256 | 1068 | sorted_t[i] = t_points_[idx[i]]; | |
| 257 | 1068 | sorted_trials[i] = trial_points_[idx[i]]; | |
| 258 | } | ||
| 259 | |||
| 260 | 140 | t_points_ = std::move(sorted_t); | |
| 261 | 140 | trial_points_ = std::move(sorted_trials); | |
| 262 | 140 | } | |
| 263 | |||
| 264 | 140 | double AlekseevAGlobalOptCharsMPI::ComputeLipschitzEstimate() { | |
| 265 | 140 | double max_slope = 0.0; | |
| 266 | |||
| 267 |
2/2✓ Branch 0 taken 928 times.
✓ Branch 1 taken 140 times.
|
1068 | for (std::size_t i = 1; i < t_points_.size(); ++i) { |
| 268 | 928 | const double dt = t_points_[i] - t_points_[i - 1]; | |
| 269 |
1/2✓ Branch 0 taken 928 times.
✗ Branch 1 not taken.
|
928 | if (dt > 1e-15) { |
| 270 | 928 | const double dz = std::abs(trial_points_[i].z - trial_points_[i - 1].z); | |
| 271 | 928 | max_slope = std::max(max_slope, dz / dt); | |
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 275 |
2/2✓ Branch 0 taken 128 times.
✓ Branch 1 taken 12 times.
|
140 | return (max_slope > 0.0) ? max_slope : 1.0; |
| 276 | } | ||
| 277 | |||
| 278 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
|
140 | void AlekseevAGlobalOptCharsMPI::CharacteristicsParallelComputed(double m_val, std::vector<double> &characteristics) { |
| 279 | 140 | const int interval_count = static_cast<int>(t_points_.size()) - 1; | |
| 280 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
|
140 | if (interval_count <= 0) { |
| 281 | characteristics.clear(); | ||
| 282 | ✗ | return; | |
| 283 | } | ||
| 284 | |||
| 285 | 140 | std::vector<int> counts; | |
| 286 | 140 | std::vector<int> displs; | |
| 287 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | ComputeDistribution(interval_count, world_size_, counts, displs); |
| 288 | |||
| 289 | 140 | std::vector<double> packed_intervals; | |
| 290 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
|
140 | if (world_rank_ == 0) { |
| 291 |
1/2✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
|
70 | PackIntervalsData(t_points_, trial_points_, interval_count, packed_intervals); |
| 292 | } else { | ||
| 293 |
1/2✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
|
70 | packed_intervals.resize(static_cast<std::size_t>(interval_count) * 4); |
| 294 | } | ||
| 295 | |||
| 296 |
1/4✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
140 | std::vector<int> send_counts(static_cast<std::size_t>(world_size_)); |
| 297 |
1/4✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
140 | std::vector<int> send_displs(static_cast<std::size_t>(world_size_)); |
| 298 |
2/2✓ Branch 0 taken 280 times.
✓ Branch 1 taken 140 times.
|
420 | for (int i = 0; i < world_size_; ++i) { |
| 299 | 280 | send_counts[static_cast<std::size_t>(i)] = counts[static_cast<std::size_t>(i)] * 4; | |
| 300 | 280 | send_displs[static_cast<std::size_t>(i)] = displs[static_cast<std::size_t>(i)] * 4; | |
| 301 | } | ||
| 302 | |||
| 303 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | const int local_interval_count = counts[static_cast<std::size_t>(world_rank_)]; |
| 304 |
1/4✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
140 | std::vector<double> local_interval_data(static_cast<std::size_t>(local_interval_count) * 4); |
| 305 | |||
| 306 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | MPI_Scatterv(packed_intervals.data(), send_counts.data(), send_displs.data(), MPI_DOUBLE, local_interval_data.data(), |
| 307 | local_interval_count * 4, MPI_DOUBLE, 0, MPI_COMM_WORLD); | ||
| 308 | |||
| 309 | 140 | std::vector<double> local_chars; | |
| 310 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | ComputeLocalCharacteristics(local_interval_data, local_interval_count, m_val, local_chars); |
| 311 | |||
| 312 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | characteristics.resize(static_cast<std::size_t>(interval_count)); |
| 313 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | GatherCharacteristicsToRoot(local_chars, counts, displs, world_rank_, world_size_, characteristics); |
| 314 | |||
| 315 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | MPI_Bcast(characteristics.data(), interval_count, MPI_DOUBLE, 0, MPI_COMM_WORLD); |
| 316 | } | ||
| 317 | |||
| 318 | ✗ | int AlekseevAGlobalOptCharsMPI::BestInterval(const std::vector<double> &characteristics) { | |
| 319 | double best_char = -std::numeric_limits<double>::max(); | ||
| 320 | int best_idx = 0; | ||
| 321 | |||
| 322 |
2/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 928 times.
✓ Branch 3 taken 140 times.
|
1068 | for (std::size_t i = 0; i < characteristics.size(); ++i) { |
| 323 |
2/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 330 times.
✓ Branch 3 taken 598 times.
|
928 | if (characteristics[i] > best_char) { |
| 324 | best_char = characteristics[i]; | ||
| 325 | 330 | best_idx = static_cast<int>(i); | |
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 329 | ✗ | return best_idx; | |
| 330 | } | ||
| 331 | |||
| 332 | 64 | double AlekseevAGlobalOptCharsMPI::PerformTrial(double t) { | |
| 333 | const auto &input = GetInput(); | ||
| 334 | |||
| 335 | 64 | const double x = PeanoToX(t, input.x_min, input.x_max, peano_level_); | |
| 336 | 64 | const double y = PeanoToY(t, input.y_min, input.y_max, peano_level_); | |
| 337 | |||
| 338 | 64 | return input.func(x, y); | |
| 339 | } | ||
| 340 | |||
| 341 | 152 | void AlekseevAGlobalOptCharsMPI::BroadcastTrialData() { | |
| 342 | 152 | int n = static_cast<int>(t_points_.size()); | |
| 343 | 152 | MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 344 | |||
| 345 |
2/2✓ Branch 0 taken 76 times.
✓ Branch 1 taken 76 times.
|
152 | if (world_rank_ != 0) { |
| 346 | 76 | t_points_.resize(static_cast<std::size_t>(n)); | |
| 347 | 76 | trial_points_.resize(static_cast<std::size_t>(n)); | |
| 348 | } | ||
| 349 | |||
| 350 | 152 | MPI_Bcast(t_points_.data(), n, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 351 | |||
| 352 | 152 | std::vector<double> packed_trials(static_cast<std::size_t>(n) * 3); | |
| 353 | |||
| 354 |
2/2✓ Branch 0 taken 76 times.
✓ Branch 1 taken 76 times.
|
152 | if (world_rank_ == 0) { |
| 355 |
2/2✓ Branch 0 taken 610 times.
✓ Branch 1 taken 76 times.
|
686 | for (int i = 0; i < n; ++i) { |
| 356 | 610 | const auto idx = static_cast<std::size_t>(i); | |
| 357 | 610 | packed_trials[(idx * 3) + 0] = trial_points_[idx].x; | |
| 358 | 610 | packed_trials[(idx * 3) + 1] = trial_points_[idx].y; | |
| 359 | 610 | packed_trials[(idx * 3) + 2] = trial_points_[idx].z; | |
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 |
1/2✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
|
152 | MPI_Bcast(packed_trials.data(), n * 3, MPI_DOUBLE, 0, MPI_COMM_WORLD); |
| 364 | |||
| 365 |
2/2✓ Branch 0 taken 76 times.
✓ Branch 1 taken 76 times.
|
152 | if (world_rank_ != 0) { |
| 366 |
2/2✓ Branch 0 taken 610 times.
✓ Branch 1 taken 76 times.
|
686 | for (int i = 0; i < n; ++i) { |
| 367 | 610 | const auto idx = static_cast<std::size_t>(i); | |
| 368 | 610 | trial_points_[idx].x = packed_trials[(idx * 3) + 0]; | |
| 369 | 610 | trial_points_[idx].y = packed_trials[(idx * 3) + 1]; | |
| 370 | 610 | trial_points_[idx].z = packed_trials[(idx * 3) + 2]; | |
| 371 | } | ||
| 372 | } | ||
| 373 | 152 | } | |
| 374 | |||
| 375 | } // namespace alekseev_a_global_opt_chars | ||
| 376 |