GCC Code Coverage Report


Directory: ./
File: tasks/kutergin_v_trapezoid_method_of_integration/mpi/src/trapezoid_integration_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 0 42 0.0%
Functions: 0 6 0.0%
Branches: 0 16 0.0%

Line Branch Exec Source
1 #include "../include/trapezoid_integration_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cmath>
6
7 #include "../../common/include/common.hpp"
8
9 namespace kutergin_v_trapezoid_mpi {
10
11 double Func(double x) // интегрируемая функция для примера
12 {
13 return x * x;
14 }
15
16 TrapezoidIntegrationMPI::TrapezoidIntegrationMPI(const kutergin_v_trapezoid_seq::InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask()); // установка типа задачи
18 GetInput() = in; // сохранение входных данных
19 GetOutput() = 0.0; // инициализация выходных данных
20 }
21
22 bool TrapezoidIntegrationMPI::ValidationImpl() {
23 return (GetInput().a <= GetInput().b) && (GetInput().n > 0);
24 }
25
26 bool TrapezoidIntegrationMPI::PreProcessingImpl() {
27 return true;
28 }
29
30 bool TrapezoidIntegrationMPI::RunImpl() {
31 int process_rank = 0;
32 int process_count = 0;
33 MPI_Comm_rank(MPI_COMM_WORLD, &process_rank);
34 MPI_Comm_size(MPI_COMM_WORLD, &process_count);
35
36 kutergin_v_trapezoid_seq::InType broadcast_data;
37 if (process_rank == 0) {
38 broadcast_data = GetInput();
39 }
40
41 // Каждое поле рассылается отдельно
42 MPI_Bcast(&broadcast_data.a, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
43 MPI_Bcast(&broadcast_data.b, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
44 MPI_Bcast(&broadcast_data.n, 1, MPI_INT, 0, MPI_COMM_WORLD);
45
46 double a = broadcast_data.a;
47 double b = broadcast_data.b;
48 int n = broadcast_data.n;
49 double h = (b - a) / n;
50
51 const int base_n = n / process_count; // целое часть от деления числа разбиений на число процессов
52 const int remainder = n % process_count; // остаток от деления числа разбиений на число процессов
53
54 const int local_n = base_n + (process_rank < remainder ? 1 : 0); // количество разбиений (трапеций) на один процесс
55
56 int start_index = 0;
57 if (process_rank < remainder) {
58 start_index = process_rank * (base_n + 1);
59 } else {
60 start_index = (remainder * (base_n + 1)) + ((process_rank - remainder) * base_n);
61 }
62
63 double local_a = a + (start_index * h); // начало отрезка для текущего процесса
64
65 // локальные вычисления
66 double local_sum = 0.0;
67 if (local_n > 0) {
68 local_sum = (Func(local_a) + Func(local_a + (local_n * h))) / 2.0;
69 }
70
71 for (int i = 1; i < local_n; ++i) {
72 local_sum += Func(local_a + (i * h));
73 }
74
75 // агрегация
76 double global_sum = 0.0;
77 MPI_Reduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
78
79 if (process_rank == 0) {
80 GetOutput() = global_sum * h;
81 }
82
83 return true;
84 }
85
86 bool TrapezoidIntegrationMPI::PostProcessingImpl() {
87 return true;
88 }
89
90 } // namespace kutergin_v_trapezoid_mpi
91