GCC Code Coverage Report


Directory: ./
File: tasks/tsibareva_e_ribbon_horizontal_matrix_mult_vector/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 0 82 0.0%
Functions: 0 10 0.0%
Branches: 0 56 0.0%

Line Branch Exec Source
1 #include "tsibareva_e_ribbon_horizontal_matrix_mult_vector/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <vector>
7
8 #include "tsibareva_e_ribbon_horizontal_matrix_mult_vector/common/include/common.hpp"
9
10 namespace tsibareva_e_ribbon_horizontal_matrix_mult_vector {
11
12 TsibarevaERibbonHorizontalMatrixMultVectorMPI::TsibarevaERibbonHorizontalMatrixMultVectorMPI(const InType &in) {
13 SetTypeOfTask(GetStaticTypeOfTask());
14
15 int world_rank = 0;
16 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
17
18 GetInput() = in;
19
20 if (world_rank == 0) {
21 input_matrix_ = std::get<0>(GetInput());
22 rows_ = std::get<1>(GetInput());
23 cols_ = std::get<2>(GetInput());
24 local_vector_ = std::get<3>(GetInput());
25 } else {
26 input_matrix_ = std::vector<int>();
27 rows_ = -1;
28 cols_ = -1;
29 local_vector_ = std::vector<int>();
30 }
31 GetOutput() = std::vector<int>();
32 }
33
34 bool TsibarevaERibbonHorizontalMatrixMultVectorMPI::ValidationImpl() {
35 return true;
36 }
37
38 bool TsibarevaERibbonHorizontalMatrixMultVectorMPI::PreProcessingImpl() {
39 return true;
40 }
41
42 bool TsibarevaERibbonHorizontalMatrixMultVectorMPI::RunImpl() {
43 int world_rank = 0;
44 int world_size = 0;
45 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
46 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
47
48 BroadcastMatrixDimensions();
49
50 if (rows_ == 0 || cols_ == 0) {
51 GetOutput() = std::vector<int>();
52 return true;
53 }
54
55 BroadcastVector();
56
57 int rows_base = rows_ / world_size;
58 int remainder = rows_ % world_size;
59 local_rows_ = rows_base + (world_rank < remainder ? 1 : 0);
60
61 std::vector<int> send_counts;
62 std::vector<int> displacements;
63 PrepareScatterParameters(world_rank, world_size, send_counts, displacements);
64
65 ScatterMatrixData(world_rank, send_counts, displacements);
66
67 std::vector<int> local_result = CalculateMultiplyLocalPart();
68
69 std::vector<int> recv_counts(world_size);
70 std::vector<int> displs(world_size);
71 std::vector<int> global_result(rows_);
72
73 int mdisplace = 0;
74 for (int i = 0; i < world_size; i++) {
75 int proc_rows = rows_base + (i < remainder ? 1 : 0);
76 recv_counts[i] = proc_rows;
77 displs[i] = mdisplace;
78 mdisplace += proc_rows;
79 }
80
81 MPI_Allgatherv(local_result.data(), local_rows_, MPI_INT, global_result.data(), recv_counts.data(), displs.data(),
82 MPI_INT, MPI_COMM_WORLD);
83
84 GetOutput() = global_result;
85 return true;
86 }
87
88 void TsibarevaERibbonHorizontalMatrixMultVectorMPI::BroadcastMatrixDimensions() {
89 MPI_Bcast(&rows_, 1, MPI_INT, 0, MPI_COMM_WORLD);
90 MPI_Bcast(&cols_, 1, MPI_INT, 0, MPI_COMM_WORLD);
91 }
92
93 void TsibarevaERibbonHorizontalMatrixMultVectorMPI::BroadcastVector() {
94 local_vector_.resize(cols_);
95 MPI_Bcast(local_vector_.data(), cols_, MPI_INT, 0, MPI_COMM_WORLD);
96 }
97
98 void TsibarevaERibbonHorizontalMatrixMultVectorMPI::PrepareScatterParameters(int world_rank, int world_size,
99 std::vector<int> &send_counts,
100 std::vector<int> &displacements) const {
101 send_counts.resize(world_size);
102 displacements.resize(world_size);
103
104 if (world_rank == 0) {
105 int rows_base = rows_ / world_size;
106 int remainder = rows_ % world_size;
107 int displ = 0;
108
109 for (int i = 0; i < world_size; i++) {
110 int proc_rows = rows_base + (i < remainder ? 1 : 0);
111 send_counts[i] = proc_rows * cols_;
112 displacements[i] = displ;
113 displ += send_counts[i];
114 }
115 }
116
117 MPI_Bcast(send_counts.data(), world_size, MPI_INT, 0, MPI_COMM_WORLD);
118 MPI_Bcast(displacements.data(), world_size, MPI_INT, 0, MPI_COMM_WORLD);
119 }
120
121 void TsibarevaERibbonHorizontalMatrixMultVectorMPI::ScatterMatrixData(int world_rank,
122 const std::vector<int> &send_counts,
123 const std::vector<int> &displacements) {
124 local_flat_data_.resize(static_cast<size_t>(local_rows_) * cols_);
125 MPI_Scatterv(world_rank == 0 ? input_matrix_.data() : nullptr, send_counts.data(), displacements.data(), MPI_INT,
126 local_flat_data_.data(), static_cast<int>(local_flat_data_.size()), MPI_INT, 0, MPI_COMM_WORLD);
127 }
128
129 std::vector<int> TsibarevaERibbonHorizontalMatrixMultVectorMPI::CalculateMultiplyLocalPart() {
130 std::vector<int> local_result(local_rows_, 0);
131
132 for (int local_row = 0; local_row < local_rows_; local_row++) {
133 int sum = 0;
134 for (int col = 0; col < cols_; col++) {
135 int matrix_idx = (local_row * cols_) + col;
136 sum += local_flat_data_[matrix_idx] * local_vector_[col];
137 }
138 local_result[local_row] = sum;
139 }
140
141 return local_result;
142 }
143
144 bool TsibarevaERibbonHorizontalMatrixMultVectorMPI::PostProcessingImpl() {
145 return true;
146 }
147
148 } // namespace tsibareva_e_ribbon_horizontal_matrix_mult_vector
149