| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "maslova_u_row_matr_vec_mult/mpi/include/ops_mpi.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | |||
| 5 | #include <cstddef> | ||
| 6 | #include <cstdint> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "maslova_u_row_matr_vec_mult/common/include/common.hpp" | ||
| 10 | |||
| 11 | namespace maslova_u_row_matr_vec_mult { | ||
| 12 | |||
| 13 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | MaslovaURowMatrVecMultMPI::MaslovaURowMatrVecMultMPI(const InType &in) { |
| 14 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 15 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | GetInput() = in; |
| 16 | 14 | } | |
| 17 | |||
| 18 | 14 | bool MaslovaURowMatrVecMultMPI::ValidationImpl() { | |
| 19 | 14 | int rank = 0; | |
| 20 | 14 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 21 | 14 | int flag = 0; | |
| 22 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | if (rank == 0) { |
| 23 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (GetInput().first.cols != GetInput().second.size()) { |
| 24 | ✗ | flag = 1; | |
| 25 | } | ||
| 26 | } | ||
| 27 | 14 | MPI_Bcast(&flag, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 28 | 14 | return flag == 0; | |
| 29 | } | ||
| 30 | |||
| 31 | 14 | bool MaslovaURowMatrVecMultMPI::PreProcessingImpl() { | |
| 32 | 14 | return true; | |
| 33 | } | ||
| 34 | |||
| 35 | 14 | bool MaslovaURowMatrVecMultMPI::RunImpl() { | |
| 36 | 14 | int rank = 0; | |
| 37 | 14 | int proc_size = 0; | |
| 38 | 14 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 39 | 14 | MPI_Comm_size(MPI_COMM_WORLD, &proc_size); | |
| 40 | |||
| 41 | 14 | uint64_t rows = 0; | |
| 42 | 14 | uint64_t cols = 0; | |
| 43 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | if (rank == 0) { |
| 44 | 7 | rows = static_cast<uint64_t>(GetInput().first.rows); | |
| 45 | 7 | cols = static_cast<uint64_t>(GetInput().first.cols); | |
| 46 | } | ||
| 47 | 14 | MPI_Bcast(&rows, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); | |
| 48 | 14 | MPI_Bcast(&cols, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); // рассылаем размеры матрицы | |
| 49 | |||
| 50 | 14 | MPI_Datatype row_type = MPI_DATATYPE_NULL; // для удобства создадим новый тип строка | |
| 51 | 14 | MPI_Type_contiguous(static_cast<int>(cols), MPI_DOUBLE, &row_type); | |
| 52 | 14 | MPI_Type_commit(&row_type); | |
| 53 | |||
| 54 | 14 | std::vector<double> vec(cols); | |
| 55 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | if (rank == 0) { |
| 56 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | vec = GetInput().second; |
| 57 | } | ||
| 58 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | MPI_Bcast(vec.data(), static_cast<int>(cols), MPI_DOUBLE, 0, MPI_COMM_WORLD); // рассылаем вектор |
| 59 | |||
| 60 |
1/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
14 | std::vector<int> row_cnt(proc_size); // сколько срок получит каждый процесс |
| 61 |
1/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
14 | std::vector<int> row_start(proc_size); // с какой строки начинается порция процесса |
| 62 | |||
| 63 | 14 | int q = static_cast<int>(rows) / proc_size; | |
| 64 | 14 | int r = static_cast<int>(rows) % proc_size; | |
| 65 | |||
| 66 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
|
42 | for (int i = 0; i < proc_size; ++i) { |
| 67 |
4/4✓ Branch 0 taken 26 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 14 times.
|
54 | row_cnt[i] = q + (i < r ? 1 : 0); |
| 68 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
|
28 | row_start[i] = (i == 0) ? 0 : row_start[i - 1] + row_cnt[i - 1]; |
| 69 | } | ||
| 70 | |||
| 71 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | int local_rows = row_cnt[rank]; |
| 72 |
1/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
14 | std::vector<double> local_matrix(local_rows * cols); |
| 73 | |||
| 74 |
3/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
|
21 | MPI_Scatterv(rank == 0 ? GetInput().first.data.data() : nullptr, row_cnt.data(), row_start.data(), row_type, |
| 75 | local_matrix.data(), static_cast<int>(local_rows * cols), MPI_DOUBLE, 0, | ||
| 76 | MPI_COMM_WORLD); // рассылаем строки матрицы | ||
| 77 | |||
| 78 |
1/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
14 | std::vector<double> local_res(local_rows, 0.0); |
| 79 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 14 times.
|
29 | for (int i = 0; i < local_rows; ++i) { |
| 80 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 15 times.
|
47 | for (size_t j = 0; j < cols; ++j) { |
| 81 | 32 | local_res[i] += local_matrix[(i * cols) + j] * vec[j]; // вычисляем локально | |
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | if (rank == 0) { |
| 86 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | GetOutput().resize(rows); |
| 87 | } | ||
| 88 | |||
| 89 |
3/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
|
21 | MPI_Gatherv(local_res.data(), local_rows, MPI_DOUBLE, rank == 0 ? GetOutput().data() : nullptr, row_cnt.data(), |
| 90 | row_start.data(), MPI_DOUBLE, 0, MPI_COMM_WORLD); // собираем результаты | ||
| 91 | |||
| 92 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | MPI_Type_free(&row_type); // очищаем созданный ип |
| 93 | |||
| 94 | 14 | return true; | |
| 95 | } | ||
| 96 | |||
| 97 | 14 | bool MaslovaURowMatrVecMultMPI::PostProcessingImpl() { | |
| 98 | 14 | return true; | |
| 99 | } | ||
| 100 | |||
| 101 | } // namespace maslova_u_row_matr_vec_mult | ||
| 102 |