Как исправить ошибку: «MPI_ERR_BUFFER: invalid buffer pointer» и что это значит?

Я пишу программу на языке C, использующую MPI для уравнения колебаний струны в двумерном случае. Программа корректно работает на разном количестве потоков, но на одном потоке считает неправильно, а на 6 и 8 потоках выдает ошибку:

[manage-01:17217] *** An error occurred in MPI_Irecv

[manage-01:17217] *** reported by process [927989761,5]

[manage-01:17217] *** on communicator MPI_COMM_WORLD

[manage-01:17217] *** MPI_ERR_BUFFER: invalid buffer pointer

[manage-01:17217] *** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,

[manage-01:17217] *** and potentially your MPI job)

[manage-01.bigdata.local:17202] 5 more processes have sent help message help-mpi-btl-tcp.txt / invalid if_inexclude

[manage-01.bigdata.local:17202] Set MCA parameter "orte_base_help_aggregate" to 0 to see all help / error messages

‘’’

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>

#define TAG_TOP_TO_BOT 123
#define TAG_BOT_TO_TOP 321

double phi(double x, double y)
{
    return sin(3 * x) * cos(4 * y);
}

double psi_mu_1(double x, double y)
{
    return 0;
}

double f(double a, double t, double x, double y)
{
    return (25 * a * a - 4) * cos(2 * t) * sin(3 * x) * cos(4 * y);
}

double mu_2(double t, double x)
{
    return cos(2 * t) * sin(3 * x);
}

double mu_4(double t, double x, double Ly)
{
    return cos(2 * t) * sin(3 * x) * cos(4 * Ly);
}

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

int size, rank;

MPI_Comm_size(MPI_COMM_WORLD, &size);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

double time1;
if (rank == 0)
{
    time1 = MPI_Wtime();
}

int N, Mx, My;
N = 400;
Mx = 200;
My = 200;

double T, Lx, Ly;
T = 1;
Lx = 1;
Ly = 1;

double tau, hx, hy;
tau = T / N;
hx = Lx / Mx;
hy = Ly / My;

double a = 1;

double norm_L_2 = 0, norm_c = 0;
double norm_L_2_global, norm_c_global;


const int 
    i_size = (My+1) / size + (rank < (My+1) % size ? 1 : 0),
    i_size_with_overlap = i_size + (!rank || rank == size-1 ? 1 : 2),
    i_min = rank < (My+1) % size ? i_size * rank : (My+1) - (size-rank)*i_size,
    i_max = i_min + i_size,
    i_min_with_overlap = i_min - (rank > 0),
    i_max_with_overlap = i_max + (rank < size-1);

double** u_0;
double** u_1;
double** u_2;

u_0 = malloc(i_size_with_overlap * sizeof(double*));
u_1 = malloc(i_size_with_overlap * sizeof(double*));
u_2 = malloc(i_size_with_overlap * sizeof(double*));

for (int i = 0; i < i_size_with_overlap; ++i)
{
    u_0[i] = malloc((Mx + 1) * sizeof(double));
    u_1[i] = malloc((Mx + 1) * sizeof(double));
    u_2[i] = malloc((Mx + 1) * sizeof(double));
}

double t = 0;

for(int i_2 = i_min_with_overlap; i_2 < i_max_with_overlap; i_2++)
{
    for(int j = 0; j < Mx + 1; j++)
    {
        const int i = i_2 - i_min_with_overlap;
        u_1[i][j] = phi(j * hx, i_2 * hy);
    }
}

for(int i_2 = fmax(1, i_min); i_2 < fmin(My, i_max); i_2++)
{
    for(int j = 1; j < Mx; j++)
    {
        const int i = i_2 - i_min_with_overlap;
        u_2[i][j] = u_1[i][j] + tau * (psi_mu_1(j * hx, i_2 * hy) + tau / 2 * (a * a * 
        ((u_1[i + 1][j] - 2 * u_1[i][j] + u_1[i - 1][j]) / (hy * hy) + (u_1[i][j + 1] - 2 * u_1[i][j] 
        + u_1[i][j - 1]) / (hx * hx)) + f(a, t, j * hx, i_2 * hy)));
    }
}

t += tau;

for(int i_2 = fmax(1, i_min); i_2 < fmin(My, i_max); i_2++)
{
    const int i = i_2 - i_min_with_overlap;
    u_2[i][0] = psi_mu_1(t, Lx);
    u_2[i][Mx] = mu_4(t, Lx, i_2 * hy);
}

if (rank == 0)
{
    for (int j = 0; j <= Mx; ++j)
    {
        u_2[i_min - i_min_with_overlap][j] = mu_2(t, j * hx);
    }
}
else if (rank == size - 1)
for(int j = 0; j < Mx + 1; j++)
{
    u_2[i_max - 1 - i_min_with_overlap][j] = mu_4(t, j * hx, Ly);
}

const int bot = (rank - 1 < 0) ? (MPI_PROC_NULL) : (rank - 1);
const int top = (rank + 1 >= size) ? (MPI_PROC_NULL) : (rank + 1);

while(t < T - tau / 2)
{
    MPI_Request request[4];

MPI_Irecv(u_2[i_max - i_min_with_overlap], Mx+1, MPI_DOUBLE, top, TAG_TOP_TO_BOT, MPI_COMM_WORLD, &request[0]);

MPI_Irecv(u_2[i_min_with_overlap - i_min_with_overlap], Mx+1, MPI_DOUBLE, bot, TAG_BOT_TO_TOP, MPI_COMM_WORLD, &request[1]);

MPI_Isend(u_2[i_max-1 - i_min_with_overlap], Mx+1, MPI_DOUBLE, top, TAG_BOT_TO_TOP, MPI_COMM_WORLD, &request[2]);

MPI_Isend(u_2[i_min - i_min_with_overlap], Mx+1, MPI_DOUBLE, bot, TAG_TOP_TO_BOT, MPI_COMM_WORLD, &request[3]);

MPI_Waitall(4, request, MPI_STATUS_IGNORE);
    

    double** tmp = u_0;
    u_0 = u_1;
    u_1 = u_2;
    u_2 = tmp;

    for(int i_2 = fmax(1, i_min); i_2 < fmin(My, i_max); i_2++)
    {
        for(int j = 1; j < Mx; j++)
        {
            const int i = i_2 - i_min_with_overlap;
            u_2[i][j] = 2 * u_1[i][j] - u_0[i][j]
            + tau * tau * (a * a * ((u_1[i + 1][j] - 2 * u_1[i][j] + u_1[i - 1][j]) / (hy * hy)
            + (u_1[i][j + 1] - 2 * u_1[i][j] + u_1[i][j - 1]) / (hx * hx)) + f(a, t, j * hx, i_2 * hy));
        }
    }

    t += tau;

    for(int i_2 = fmax(1, i_min); i_2 < fmin(My, i_max); i_2++)
    {
        const int i = i_2 - i_min_with_overlap;
        u_2[i][0] = psi_mu_1(t, Lx);
        u_2[i][Mx] = mu_4(t, Lx, i_2 * hy);
    }

    if (rank == 0)
    {
        for(int j = 0; j < Mx + 1; j++)
        {
            u_2[i_min - i_min_with_overlap][j] = mu_2(t, j * hx);
        }
    }
    else if (rank == size - 1)
    {
        for(int j = 0; j < Mx + 1; j++)
        {
            u_2[i_max-1 - i_min_with_overlap][j] = mu_4(t, j * hx, Ly);
        }
    }
}

for(int i_2 = i_min; i_2 < i_max; i_2++)
{
    for(int j = 0; j <= Mx; ++j)
    {
        const int i = i_2 - i_min_with_overlap;
        const double u_t = mu_4(T, j * hx, i_2 * hy) -  u_2[i][j];
        norm_L_2 += u_t * u_t;
        norm_c = fmax(norm_c, fabs(u_t));
    }
}

MPI_Reduce(&norm_L_2, &norm_L_2_global, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

if (!rank)
{
    norm_L_2_global = sqrt(hx * hy * norm_L_2_global);
}

MPI_Reduce(&norm_c, &norm_c_global, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);

if (rank == 0)
{
    printf("%.16lf, %.16lf, Time = %.16lf\n", norm_L_2_global, norm_c_global, MPI_Wtime() - time1);
}

MPI_Finalize();

return 0;
}

‘’’


Ответы (0 шт):