| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "gauss_jordan/mpi/include/ops_mpi.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cmath> | ||
| 7 | #include <cstddef> | ||
| 8 | #include <utility> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | #include "gauss_jordan/common/include/common.hpp" | ||
| 12 | |||
| 13 | namespace gauss_jordan { | ||
| 14 | |||
| 15 | namespace { | ||
| 16 | |||
| 17 | constexpr double kEpsilon = 1e-12; | ||
| 18 | |||
| 19 | inline bool IsNumericallyZero(double value) { | ||
| 20 |
6/6✓ Branch 0 taken 142 times.
✓ Branch 1 taken 98 times.
✓ Branch 2 taken 142 times.
✓ Branch 3 taken 98 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 98 times.
|
582 | return std::fabs(value) < kEpsilon; |
| 21 | } | ||
| 22 | |||
| 23 | bool IsZeroRow(const std::vector<double> &row, int columns_minus_one) { | ||
| 24 |
2/4✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 240 times.
✗ Branch 3 not taken.
|
480 | for (int j = 0; j < columns_minus_one; ++j) { |
| 25 |
4/4✓ Branch 0 taken 142 times.
✓ Branch 1 taken 98 times.
✓ Branch 2 taken 142 times.
✓ Branch 3 taken 98 times.
|
480 | if (!IsNumericallyZero(row[j])) { |
| 26 | return false; | ||
| 27 | } | ||
| 28 | } | ||
| 29 | return true; | ||
| 30 | } | ||
| 31 | |||
| 32 | bool ValidateMatrixDimensions(const std::vector<std::vector<double>> &augmented_matrix, int equations_count, | ||
| 33 | int augmented_columns, int rank) { | ||
| 34 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | if (rank == 0) { |
| 35 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 16 times.
|
49 | for (int i = 1; i < equations_count; ++i) { |
| 36 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | if (augmented_matrix[i].size() != static_cast<size_t>(augmented_columns)) { |
| 37 | return false; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | } | ||
| 41 | return true; | ||
| 42 | } | ||
| 43 | |||
| 44 | bool CheckIfZeroMatrix(const std::vector<std::vector<double>> &augmented_matrix, int equations_count, | ||
| 45 | int augmented_columns, int rank) { | ||
| 46 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | if (rank == 0) { |
| 47 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | for (int i = 0; i < equations_count; ++i) { |
| 48 |
1/2✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
|
18 | for (int j = 0; j < augmented_columns; ++j) { |
| 49 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
|
18 | if (std::abs(augmented_matrix[i][j]) > 1e-12) { |
| 50 | return false; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | ||
| 55 | return true; | ||
| 56 | } | ||
| 57 | |||
| 58 | void HandleRankZeroOutput(int rank, std::vector<double> &output, std::vector<double> result) { | ||
| 59 | ✗ | if (rank == 0) { | |
| 60 | output = std::move(result); | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | 32 | bool ShouldReturnEarly(int rank, const std::vector<std::vector<double>> &matrix, int equations_count, | |
| 65 | int augmented_columns, std::vector<double> &output) { // Добавлен параметр output | ||
| 66 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
|
32 | if (augmented_columns == 0) { |
| 67 | ✗ | HandleRankZeroOutput(rank, output, std::vector<double>()); | |
| 68 | ✗ | MPI_Barrier(MPI_COMM_WORLD); | |
| 69 | ✗ | return true; | |
| 70 | } | ||
| 71 | |||
| 72 | 32 | bool valid_matrix = ValidateMatrixDimensions(matrix, equations_count, augmented_columns, rank); | |
| 73 | 32 | MPI_Bcast(&valid_matrix, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD); | |
| 74 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
|
32 | if (!valid_matrix) { |
| 75 | ✗ | HandleRankZeroOutput(rank, output, std::vector<double>()); | |
| 76 | ✗ | MPI_Barrier(MPI_COMM_WORLD); | |
| 77 | ✗ | return true; | |
| 78 | } | ||
| 79 | |||
| 80 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
|
32 | if (augmented_columns <= 1) { |
| 81 | ✗ | HandleRankZeroOutput(rank, output, std::vector<double>()); | |
| 82 | ✗ | MPI_Barrier(MPI_COMM_WORLD); | |
| 83 | ✗ | return true; | |
| 84 | } | ||
| 85 | |||
| 86 | 32 | bool is_zero_matrix = CheckIfZeroMatrix(matrix, equations_count, augmented_columns, rank); | |
| 87 | 32 | MPI_Bcast(&is_zero_matrix, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD); | |
| 88 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
|
32 | if (is_zero_matrix) { |
| 89 | ✗ | HandleRankZeroOutput(rank, output, std::vector<double>()); | |
| 90 | ✗ | MPI_Barrier(MPI_COMM_WORLD); | |
| 91 | ✗ | return true; | |
| 92 | } | ||
| 93 | |||
| 94 | return false; | ||
| 95 | } | ||
| 96 | |||
| 97 | bool HasValidRank(int global_rank, int augmented_columns, int equations_count) { | ||
| 98 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | return global_rank >= augmented_columns - 1 && global_rank >= equations_count; |
| 99 | } | ||
| 100 | |||
| 101 | void ExchangeRows(std::vector<std::vector<double>> &augmented_matrix, int first_row, int second_row, int columns) { | ||
| 102 | if (first_row == second_row) { | ||
| 103 | return; | ||
| 104 | } | ||
| 105 | |||
| 106 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 4 times.
|
18 | for (int col_idx = 0; col_idx < columns; ++col_idx) { |
| 107 | 14 | std::swap(augmented_matrix[first_row][col_idx], augmented_matrix[second_row][col_idx]); | |
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | void NormalizeRow(std::vector<std::vector<double>> &augmented_matrix, int row_index, double normalizer, int columns) { | ||
| 112 | if (IsNumericallyZero(normalizer)) { | ||
| 113 | return; | ||
| 114 | } | ||
| 115 | |||
| 116 |
2/2✓ Branch 0 taken 480 times.
✓ Branch 1 taken 98 times.
|
578 | for (int col_idx = 0; col_idx < columns; ++col_idx) { |
| 117 | 480 | augmented_matrix[row_index][col_idx] /= normalizer; | |
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | int LocatePivotIndex(const std::vector<std::vector<double>> &augmented_matrix, int start_row, int column, | ||
| 122 | int total_rows) { | ||
| 123 |
1/2✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
|
102 | for (int row_idx = start_row; row_idx < total_rows; ++row_idx) { |
| 124 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 98 times.
|
102 | if (!IsNumericallyZero(augmented_matrix[row_idx][column])) { |
| 125 | return row_idx; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | return -1; | ||
| 129 | } | ||
| 130 | |||
| 131 | 122 | void EliminateFromRow(std::vector<std::vector<double>> &augmented_matrix, int target_row, int source_row, | |
| 132 | double elimination_coefficient, int columns) { | ||
| 133 |
1/2✓ Branch 0 taken 122 times.
✗ Branch 1 not taken.
|
122 | if (IsNumericallyZero(elimination_coefficient)) { |
| 134 | return; | ||
| 135 | } | ||
| 136 | |||
| 137 |
2/2✓ Branch 0 taken 798 times.
✓ Branch 1 taken 122 times.
|
920 | for (int col_idx = 0; col_idx < columns; ++col_idx) { |
| 138 | 798 | augmented_matrix[target_row][col_idx] -= elimination_coefficient * augmented_matrix[source_row][col_idx]; | |
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | void BroadcastRow(std::vector<std::vector<double>> &augmented_matrix, int row, int columns) { | ||
| 143 | 98 | MPI_Bcast(augmented_matrix[row].data(), columns, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 144 | } | ||
| 145 | |||
| 146 | 98 | void BroadcastMatrix(std::vector<std::vector<double>> &augmented_matrix, int rows, int columns) { | |
| 147 |
2/2✓ Branch 0 taken 382 times.
✓ Branch 1 taken 98 times.
|
480 | for (int i = 0; i < rows; ++i) { |
| 148 | 382 | MPI_Bcast(augmented_matrix[i].data(), columns, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 149 | } | ||
| 150 | 98 | } | |
| 151 | |||
| 152 | int FindPivotMPI(const std::vector<std::vector<double>> &augmented_matrix, int current_row, int current_col, | ||
| 153 | int equations_count) { | ||
| 154 | return LocatePivotIndex(augmented_matrix, current_row, current_col, equations_count); | ||
| 155 | } | ||
| 156 | |||
| 157 | 98 | void ProcessPivotRow(std::vector<std::vector<double>> &augmented_matrix, int current_row, int current_col, | |
| 158 | int pivot_row, int augmented_columns) { | ||
| 159 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 94 times.
|
98 | if (pivot_row != current_row) { |
| 160 | ExchangeRows(augmented_matrix, current_row, pivot_row, augmented_columns); | ||
| 161 | } | ||
| 162 | |||
| 163 |
1/2✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
|
98 | double pivot_value = augmented_matrix[current_row][current_col]; |
| 164 |
1/2✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
|
98 | if (!IsNumericallyZero(pivot_value)) { |
| 165 | NormalizeRow(augmented_matrix, current_row, pivot_value, augmented_columns); | ||
| 166 | } | ||
| 167 | |||
| 168 | BroadcastRow(augmented_matrix, current_row, augmented_columns); | ||
| 169 | 98 | } | |
| 170 | |||
| 171 | 98 | void EliminateColumnFromOtherRows(std::vector<std::vector<double>> &augmented_matrix, int current_row, int current_col, | |
| 172 | int equations_count, int augmented_columns) { | ||
| 173 |
2/2✓ Branch 0 taken 382 times.
✓ Branch 1 taken 98 times.
|
480 | for (int row_idx = 0; row_idx < equations_count; ++row_idx) { |
| 174 |
2/2✓ Branch 0 taken 98 times.
✓ Branch 1 taken 284 times.
|
382 | if (row_idx == current_row) { |
| 175 | 98 | continue; | |
| 176 | } | ||
| 177 | |||
| 178 |
2/2✓ Branch 0 taken 122 times.
✓ Branch 1 taken 162 times.
|
284 | double coefficient = augmented_matrix[row_idx][current_col]; |
| 179 |
2/2✓ Branch 0 taken 122 times.
✓ Branch 1 taken 162 times.
|
284 | if (!IsNumericallyZero(coefficient)) { |
| 180 | 122 | EliminateFromRow(augmented_matrix, row_idx, current_row, coefficient, augmented_columns); | |
| 181 | } | ||
| 182 | } | ||
| 183 | 98 | } | |
| 184 | |||
| 185 | 32 | void TransformToReducedRowEchelonFormMPI(std::vector<std::vector<double>> &augmented_matrix, int equations_count, | |
| 186 | int augmented_columns) { | ||
| 187 | int current_row = 0; | ||
| 188 | int current_col = 0; | ||
| 189 | |||
| 190 |
3/4✓ Branch 0 taken 98 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
|
130 | while (current_row < equations_count && current_col < augmented_columns - 1) { |
| 191 | int pivot_row = FindPivotMPI(augmented_matrix, current_row, current_col, equations_count); | ||
| 192 | |||
| 193 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
|
98 | if (pivot_row == -1) { |
| 194 | ✗ | current_col++; | |
| 195 | ✗ | continue; | |
| 196 | } | ||
| 197 | |||
| 198 | 98 | ProcessPivotRow(augmented_matrix, current_row, current_col, pivot_row, augmented_columns); | |
| 199 | |||
| 200 | 98 | EliminateColumnFromOtherRows(augmented_matrix, current_row, current_col, equations_count, augmented_columns); | |
| 201 | |||
| 202 | 98 | BroadcastMatrix(augmented_matrix, equations_count, augmented_columns); | |
| 203 | 98 | MPI_Barrier(MPI_COMM_WORLD); | |
| 204 | |||
| 205 | 98 | current_row++; | |
| 206 | 98 | current_col++; | |
| 207 | } | ||
| 208 | 32 | } | |
| 209 | |||
| 210 | 32 | bool HasInconsistentEquation(const std::vector<std::vector<double>> &augmented_matrix, int equations_count, | |
| 211 | int augmented_columns) { | ||
| 212 |
2/2✓ Branch 0 taken 98 times.
✓ Branch 1 taken 32 times.
|
130 | for (int row_idx = 0; row_idx < equations_count; ++row_idx) { |
| 213 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
196 | if (IsZeroRow(augmented_matrix[row_idx], augmented_columns - 1) && |
| 214 | ✗ | !IsNumericallyZero(augmented_matrix[row_idx][augmented_columns - 1])) { | |
| 215 | return true; | ||
| 216 | } | ||
| 217 | } | ||
| 218 | return false; | ||
| 219 | } | ||
| 220 | |||
| 221 | 32 | int ComputeMatrixRank(const std::vector<std::vector<double>> &augmented_matrix, int equations_count, | |
| 222 | int augmented_columns) { | ||
| 223 | int rank = 0; | ||
| 224 |
2/2✓ Branch 0 taken 98 times.
✓ Branch 1 taken 32 times.
|
130 | for (int row_idx = 0; row_idx < equations_count; ++row_idx) { |
| 225 |
1/2✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
|
196 | if (!IsZeroRow(augmented_matrix[row_idx], augmented_columns - 1)) { |
| 226 | 98 | ++rank; | |
| 227 | } | ||
| 228 | } | ||
| 229 | 32 | return rank; | |
| 230 | } | ||
| 231 | |||
| 232 | 32 | std::vector<double> ComputeSolutionVector(const std::vector<std::vector<double>> &matrix, int n, int m) { | |
| 233 | 32 | std::vector<double> solution(m - 1, 0.0); | |
| 234 | int vars = m - 1; | ||
| 235 | 32 | int rows_to_process = (n < vars) ? n : vars; | |
| 236 | |||
| 237 |
2/2✓ Branch 0 taken 98 times.
✓ Branch 1 taken 32 times.
|
130 | for (int i = 0; i < rows_to_process; ++i) { |
| 238 | int pivot_col = -1; | ||
| 239 | |||
| 240 |
1/2✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
|
240 | for (int j = 0; j < vars; ++j) { |
| 241 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 98 times.
|
240 | if (std::abs(matrix[i][j]) > 1e-10) { |
| 242 | pivot_col = j; | ||
| 243 | break; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 |
1/2✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
|
98 | if (pivot_col >= 0) { |
| 248 | 98 | solution[pivot_col] = matrix[i][vars]; | |
| 249 | } else { | ||
| 250 | ✗ | solution[i] = 0.0; | |
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | 32 | return solution; | |
| 255 | } | ||
| 256 | |||
| 257 | 32 | void ProcessReducedMatrix(const std::vector<std::vector<double>> &augmented_matrix, int equations_count, | |
| 258 | int augmented_columns, bool &global_inconsistent, int &global_rank, | ||
| 259 | std::vector<double> &local_solution, int /*rank*/) { | ||
| 260 | 32 | bool local_inconsistent = HasInconsistentEquation(augmented_matrix, equations_count, augmented_columns); | |
| 261 | 32 | int local_rank = ComputeMatrixRank(augmented_matrix, equations_count, augmented_columns); | |
| 262 | |||
| 263 |
3/6✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
|
32 | if (!local_inconsistent && local_rank >= augmented_columns - 1 && local_rank >= equations_count) { |
| 264 | 64 | local_solution = ComputeSolutionVector(augmented_matrix, equations_count, augmented_columns); | |
| 265 | } | ||
| 266 | |||
| 267 | 32 | MPI_Reduce(&local_inconsistent, &global_inconsistent, 1, MPI_C_BOOL, MPI_LOR, 0, MPI_COMM_WORLD); | |
| 268 | 32 | MPI_Reduce(&local_rank, &global_rank, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); | |
| 269 | |||
| 270 | 32 | MPI_Bcast(&global_rank, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 271 | 32 | MPI_Bcast(&global_inconsistent, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD); | |
| 272 | 32 | } | |
| 273 | |||
| 274 | 32 | void BroadcastSolution(std::vector<double> &solution, int rank) { | |
| 275 | 32 | int solution_size = static_cast<int>(solution.size()); | |
| 276 | 32 | MPI_Bcast(&solution_size, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 277 | |||
| 278 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | if (rank != 0) { |
| 279 | 16 | solution.resize(static_cast<size_t>(solution_size)); | |
| 280 | } | ||
| 281 | |||
| 282 |
1/2✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
|
32 | if (solution_size > 0) { |
| 283 | 32 | MPI_Bcast(solution.data(), solution_size, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 284 | } | ||
| 285 | 32 | } | |
| 286 | |||
| 287 | 32 | void BroadcastDimensions(int &equations_count, int &augmented_columns) { | |
| 288 | 32 | MPI_Bcast(&equations_count, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 289 | 32 | MPI_Bcast(&augmented_columns, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 290 | 32 | } | |
| 291 | |||
| 292 | 16 | void FlattenAndBroadcastMatrix(const std::vector<std::vector<double>> &matrix, int equations_count, | |
| 293 | int augmented_columns) { | ||
| 294 | 16 | std::vector<double> flat_matrix(static_cast<size_t>(equations_count * augmented_columns)); | |
| 295 | |||
| 296 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 16 times.
|
65 | for (int i = 0; i < equations_count; ++i) { |
| 297 |
2/2✓ Branch 0 taken 240 times.
✓ Branch 1 taken 49 times.
|
289 | for (int j = 0; j < augmented_columns; ++j) { |
| 298 | 240 | size_t index = (static_cast<size_t>(i) * static_cast<size_t>(augmented_columns)) + static_cast<size_t>(j); | |
| 299 | 240 | flat_matrix[index] = matrix[i][j]; | |
| 300 | } | ||
| 301 | } | ||
| 302 | |||
| 303 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Bcast(flat_matrix.data(), equations_count * augmented_columns, MPI_DOUBLE, 0, MPI_COMM_WORLD); |
| 304 | 16 | } | |
| 305 | |||
| 306 | 16 | void ReceiveAndReconstructMatrix(std::vector<std::vector<double>> &matrix, int equations_count, int augmented_columns) { | |
| 307 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | std::vector<double> flat_matrix(static_cast<size_t>(equations_count * augmented_columns)); |
| 308 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Bcast(flat_matrix.data(), equations_count * augmented_columns, MPI_DOUBLE, 0, MPI_COMM_WORLD); |
| 309 | |||
| 310 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | matrix.resize(static_cast<size_t>(equations_count)); |
| 311 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 16 times.
|
65 | for (int i = 0; i < equations_count; ++i) { |
| 312 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | matrix[i].resize(static_cast<size_t>(augmented_columns)); |
| 313 |
2/2✓ Branch 0 taken 240 times.
✓ Branch 1 taken 49 times.
|
289 | for (int j = 0; j < augmented_columns; ++j) { |
| 314 | 240 | size_t index = (static_cast<size_t>(i) * static_cast<size_t>(augmented_columns)) + static_cast<size_t>(j); | |
| 315 | 240 | matrix[i][j] = flat_matrix[index]; | |
| 316 | } | ||
| 317 | } | ||
| 318 | 16 | } | |
| 319 | |||
| 320 | } // namespace | ||
| 321 | |||
| 322 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | GaussJordanMPI::GaussJordanMPI(const InType &in) { |
| 323 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 324 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | InType matrix_copy(in); |
| 325 | GetInput().swap(matrix_copy); | ||
| 326 | 32 | } | |
| 327 | |||
| 328 | 32 | bool GaussJordanMPI::ValidationImpl() { | |
| 329 | 32 | int rank = 0; | |
| 330 | 32 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 331 | |||
| 332 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | if (rank == 0) { |
| 333 | const auto &input_matrix = GetInput(); | ||
| 334 | |||
| 335 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | if (input_matrix.empty()) { |
| 336 | ✗ | int valid_flag = 1; | |
| 337 | ✗ | MPI_Bcast(&valid_flag, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 338 | return true; | ||
| 339 | } | ||
| 340 | |||
| 341 | size_t columns = input_matrix[0].size(); | ||
| 342 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | if (columns == 0) { |
| 343 | ✗ | int valid_flag = 0; | |
| 344 | ✗ | MPI_Bcast(&valid_flag, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 345 | return false; | ||
| 346 | } | ||
| 347 | |||
| 348 | size_t total_elements = 0; | ||
| 349 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 16 times.
|
65 | for (const auto &row : input_matrix) { |
| 350 | 49 | total_elements += row.size(); | |
| 351 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
|
49 | if (row.size() != columns) { |
| 352 | ✗ | int valid_flag = 0; | |
| 353 | ✗ | MPI_Bcast(&valid_flag, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 354 | return false; | ||
| 355 | } | ||
| 356 | } | ||
| 357 | |||
| 358 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
16 | bool is_valid = GetOutput().empty() && (total_elements == (columns * input_matrix.size())); |
| 359 | 16 | int valid_flag = is_valid ? 1 : 0; | |
| 360 | 16 | MPI_Bcast(&valid_flag, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 361 | 16 | return is_valid; | |
| 362 | } | ||
| 363 | |||
| 364 | 16 | int valid_flag = 0; | |
| 365 | 16 | MPI_Bcast(&valid_flag, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 366 | 16 | return valid_flag != 0; | |
| 367 | } | ||
| 368 | |||
| 369 | 32 | bool GaussJordanMPI::PreProcessingImpl() { | |
| 370 | 32 | int rank = 0; | |
| 371 | 32 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 372 | |||
| 373 | GetOutput().clear(); | ||
| 374 | |||
| 375 | 32 | int equations_count = 0; | |
| 376 | 32 | int augmented_columns = 0; | |
| 377 | |||
| 378 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | if (rank == 0) { |
| 379 | const auto &input_matrix = GetInput(); | ||
| 380 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | if (input_matrix.empty()) { |
| 381 | equations_count = 0; | ||
| 382 | augmented_columns = 0; | ||
| 383 | } else { | ||
| 384 | 16 | equations_count = static_cast<int>(input_matrix.size()); | |
| 385 | 16 | augmented_columns = static_cast<int>(input_matrix[0].size()); | |
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | 32 | BroadcastDimensions(equations_count, augmented_columns); | |
| 390 | |||
| 391 |
2/4✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
|
32 | if (equations_count == 0 || augmented_columns == 0) { |
| 392 | return true; | ||
| 393 | } | ||
| 394 | |||
| 395 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | if (rank == 0) { |
| 396 | 16 | FlattenAndBroadcastMatrix(GetInput(), equations_count, augmented_columns); | |
| 397 | } else { | ||
| 398 | 16 | ReceiveAndReconstructMatrix(GetInput(), equations_count, augmented_columns); | |
| 399 | } | ||
| 400 | |||
| 401 | return true; | ||
| 402 | } | ||
| 403 | |||
| 404 | 32 | bool GaussJordanMPI::RunImpl() { | |
| 405 | 32 | int rank = 0; | |
| 406 | 32 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 407 | |||
| 408 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
|
32 | if (GetInput().empty()) { |
| 409 | ✗ | HandleRankZeroOutput(rank, GetOutput(), std::vector<double>()); | |
| 410 | ✗ | MPI_Barrier(MPI_COMM_WORLD); | |
| 411 | ✗ | return true; | |
| 412 | } | ||
| 413 | |||
| 414 | 32 | std::vector<std::vector<double>> augmented_matrix = GetInput(); | |
| 415 | 32 | int equations_count = static_cast<int>(augmented_matrix.size()); | |
| 416 |
1/2✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
|
32 | int augmented_columns = (equations_count > 0) ? static_cast<int>(augmented_matrix[0].size()) : 0; |
| 417 | |||
| 418 |
2/4✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
✗ Branch 4 not taken.
|
32 | if (ShouldReturnEarly(rank, augmented_matrix, equations_count, augmented_columns, GetOutput())) { |
| 419 | return true; | ||
| 420 | } | ||
| 421 | |||
| 422 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | TransformToReducedRowEchelonFormMPI(augmented_matrix, equations_count, augmented_columns); |
| 423 | |||
| 424 | 32 | bool global_inconsistent = false; | |
| 425 | 32 | int global_rank = 0; | |
| 426 | 32 | std::vector<double> local_solution; | |
| 427 | |||
| 428 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | ProcessReducedMatrix(augmented_matrix, equations_count, augmented_columns, global_inconsistent, global_rank, |
| 429 | local_solution, rank); | ||
| 430 | |||
| 431 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | if (rank == 0) { |
| 432 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | if (global_inconsistent || !HasValidRank(global_rank, augmented_columns, equations_count)) { |
| 433 | ✗ | GetOutput() = std::vector<double>(); | |
| 434 | } else { | ||
| 435 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | GetOutput() = local_solution; |
| 436 | } | ||
| 437 | } | ||
| 438 | |||
| 439 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | BroadcastSolution(GetOutput(), rank); |
| 440 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | MPI_Barrier(MPI_COMM_WORLD); |
| 441 | return true; | ||
| 442 | 32 | } | |
| 443 | |||
| 444 | 32 | bool GaussJordanMPI::PostProcessingImpl() { | |
| 445 | 32 | return true; | |
| 446 | } | ||
| 447 | } // namespace gauss_jordan | ||
| 448 |