Как исправить ошибку: «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;
}
‘’’