#include <mpi.h>
#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

// Функция для печати матрицы (только на процессе 0)
void printMatrix(const vector<vector<double>>& A, const vector<double>& b, int rank) {
    if (rank == 0) {
        cout << "Matrix A and vector b:\n";
        for (size_t i = 0; i < A.size(); ++i) {
            for (size_t j = 0; j < A[i].size(); ++j) {
                cout << A[i][j] << "\t";
            }
            cout << "| " << b[i] << endl;
        }
        cout << endl;
    }
}

// Решение СЛАУ методом Гаусса
void gaussMPI(vector<vector<double>>& A, vector<double>& b, vector<double>& x, int rank, int size) {
    int n = A.size();

    for (int i = 0; i < n; ++i) {
        // Шаг нормализации ведущей строки
        if (rank == 0) {
            double pivot = A[i][i];
            for (int j = i; j < n; ++j) {
                A[i][j] /= pivot;
            }
            b[i] /= pivot;

            // Рассылка нормализованной строки всем процессам
            for (int proc = 1; proc < size; ++proc) {
                MPI_Send(&A[i][0], n, MPI_DOUBLE, proc, 0, MPI_COMM_WORLD);
                MPI_Send(&b[i], 1, MPI_DOUBLE, proc, 0, MPI_COMM_WORLD);
            }
        }
        else {
            // Получение нормализованной строки
            MPI_Recv(&A[i][0], n, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            MPI_Recv(&b[i], 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        }

        // Шаг устранения элементов ниже ведущего
        for (int k = rank; k < n; k += size) {
            if (k > i) {
                double coeff = A[k][i];
                for (int j = i; j < n; ++j) {
                    A[k][j] -= coeff * A[i][j];
                }
                b[k] -= coeff * b[i];
            }
        }

        // Отправка обновленных строк обратно на процесс 0
        for (int k = i + 1; k < n; ++k) {
            if (rank != 0) {
                MPI_Send(&A[k][0], n, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
                MPI_Send(&b[k], 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
            }
            else {
                for (int proc = 1; proc < size; ++proc) {
                    MPI_Recv(&A[k][0], n, MPI_DOUBLE, proc, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
                    MPI_Recv(&b[k], 1, MPI_DOUBLE, proc, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
                }
            }
        }
    }

    // Обратный ход с передачей данных между процессами
    x.resize(n, 0); // Инициализация вектора решения
    for (int i = n - 1; i >= 0; --i) {
        if (rank == 0) {
            x[i] = b[i];
            for (int j = i + 1; j < n; ++j) {
                x[i] -= A[i][j] * x[j];
            }

            // Рассылка текущего элемента решения другим процессам
            for (int proc = 1; proc < size; ++proc) {
                MPI_Send(&x[i], 1, MPI_DOUBLE, proc, 2, MPI_COMM_WORLD);
            }
        }
        else {
            // Получение текущего элемента решения
            MPI_Recv(&x[i], 1, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

            // Обновление локальной копии b для следующего шага
            if (i < n) {
                b[i] -= A[i][i + 1] * x[i];
            }
        }
    }
}

int main(int argc, char** argv) {
    MPI_Init(&argc, &argv);

    int rank, size;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    const int N = 5; // Размер матрицы
    vector<vector<double>> A(N, vector<double>(N));
    vector<double> b(N);
    vector<double> x;

    if (rank == 0) {
        // Инициализация матрицы и вектора свободных членов на процессе 0
        A = {
            {4, -1, 0, 0, 2},
            {-1, 4, -1, 0, 1},
            {0, -1, 4, -1, 0},
            {0, 0, -1, 3, -1},
            {2, 1, 0, -1, 3}
        };
        b = { 15, 10, 10, 10, 15 };

        printMatrix(A, b, rank);
    }

    // Рассылка начальных данных всем процессам
    for (int i = 0; i < N; ++i) {
        if (rank == 0) {
            for (int proc = 1; proc < size; ++proc) {
                MPI_Send(&A[i][0], N, MPI_DOUBLE, proc, 2, MPI_COMM_WORLD);
                MPI_Send(&b[i], 1, MPI_DOUBLE, proc, 2, MPI_COMM_WORLD);
            }
        }
        else {
            MPI_Recv(&A[i][0], N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            MPI_Recv(&b[i], 1, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        }
    }

    // Решение системы методом Гаусса
    gaussMPI(A, b, x, rank, size);

    if (rank == 0) {
        // Вывод решения
        cout << "Solution:\n";
        for (double xi : x) {
            cout << xi << " ";
        }
        cout << endl;
    }

    MPI_Finalize();
    return 0;
}
При запуске 1 процессоре выдает правильный ответ:
D:\Projects\shapov\mpi_metodgausa\x64\Debug>mpiexec -n 1 mpi_metodgausa.exe
Matrix A and vector b:
4       -1      0       0       2       | 15
-1      4       -1      0       1       | 10
0       -1      4       -1      0       | 10
0       0       -1      3       -1      | 10
2       1       0       -1      3       | 15

Solution:
2.17791 3.09816 4.90798 6.53374 4.69325
При запуске на других количествах процессов:
Expression: vector subscript out of range
D:\Projects\shapov\mpi_metodgausa\x64\Debug>mpiexec -n 2 mpi_metodgausa.exe
Matrix A and vector b:
4       -1      0       0       2       | 15
-1      4       -1      0       1       | 10
0       -1      4       -1      0       | 10
0       0       -1      3       -1      | 10
2       1       0       -1      3       | 15

Solution:
1.93939 2.75758 4.09091 6.36364 5

job aborted:
[ranks] message

[0] terminated

[1] process exited without calling finalize

---- error analysis -----

[1] on DESKTOP-DROGCJ7
mpi_metodgausa.exe ended prematurely and may have crashed. exit code 0xc0000409

---- error analysis -----

D:\Projects\shapov\mpi_metodgausa\x64\Debug>