使用MPI库运行C代码时出现分段错误



我在Linux系统上运行这段代码:

// mpic++ -o lab lab.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>
#define N 3 // розмір топології Гіперкуб
int main(int argc, char **argv)
{
int size, rank;
double *A, *B, *C, *subA, *subC, *subB;
int n = 500; // розмір матриць
int sub_n;   // розмір підматриць
int i, j, k;
double start_time, end_time;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// розмір підматриці для кожного процесу
sub_n = n / size;
// розбиття матриць A та B на підматриці для кожного процесу
subA = (double *)malloc(sub_n * n * sizeof(double));
subB = (double *)malloc(sub_n * sizeof(double));
subC = (double *)calloc(sub_n * n, sizeof(double));
// ініціалізація матриць A та B
for (i = 0; i < sub_n; i++)
{
for (j = 0; j < n; j++)
{
subA[i * n + j] = (1.85 * sqrt((rank * sub_n + i) + sin(j))) / (cos((rank * sub_n + i) + j) + 5);
}
subB[i] = (double)rand() / (double)(RAND_MAX / 40.0) / 4.0;
}
// ініціалізація топології "гіперкуб"
int dims[N];
int periods[N];
for (i = 0; i < N; i++)
{
dims[i] = 2;    // кількість вузлів у кожному напрямку
periods[i] = 1; // періодичність
}
MPI_Comm comm;
MPI_Cart_create(MPI_COMM_WORLD, N, dims, periods, 1, &comm);
// розрахунок координат поточного процесу в топології
int coords[N];
MPI_Cart_coords(comm, rank, N, coords);
// розрахунок сусідніх процесів у топології
int source[N], dest[N];
for (i = 0; i < N; i++)
{
MPI_Cart_shift(comm, i, 1, &source[i], &dest[i]);
}
// паралельне множення матриць
MPI_Barrier(comm);
start_time = MPI_Wtime();
// кожен процес виконує обчислення своєї частини підматриці C
for (i = 0; i < sub_n; i++)
{
for (j = 0; j < n; j++)
{
for (k = 0; k < sub_n; k++)
{
subC[i * n + j] += subA[i * n + k] * B[k * n + j];
}
}
}
// обмін даними між процесами для збору результатів в матрицю C
MPI_Datatype row;
MPI_Type_contiguous(n, MPI_DOUBLE, &row);
MPI_Type_commit(&row);
// кожен процес відправляє свою підматрицю C до головного процесу
if (rank != 0)
{
MPI_Send(subC, sub_n * n, MPI_DOUBLE, 0, 0, comm);
}
else
{
// головний процес отримує підматриці C від інших процесів та збирає їх в матрицю C
C = (double *)malloc(n * n * sizeof(double));
for (i = 0; i < sub_n; i++)
{
for (j = 0; j < n; j++)
{
C[i * n + j] = subC[i * n + j];
}
}
for (k = 1; k < size; k++)
{
MPI_Recv(subC, sub_n * n, MPI_DOUBLE, k, 0, comm, MPI_STATUS_IGNORE);
for (i = 0; i < sub_n; i++)
{
for (j = 0; j < n; j++)
{
C[(k * sub_n + i) * n + j] = subC[i * n + j];
}
}
}
}
MPI_Barrier(comm);
end_time = MPI_Wtime();
// виведення результату
if (rank == 0)
{
printf("Multiplication time: %f secondsn", end_time - start_time);
// виведення матриці C
printf("Matrix C:n");
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("%f ", C[i * n + j]);
}
printf("n");
}
}
// завершення програми та звільнення пам'яті
free(A);
free(B);
free(C);
free(subA);
free(subB);
free(subC);
MPI_Finalize();
return 0;
}

终端输出如下:

lab5:8061 terminated with signal 11 at PC=561d993e5815 SP=7ffef0233730.  Backtrace:
./lab5(+0x1815)[0x561d993e5815]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7f16bb029d90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x7f16bb029e40]
./lab5(+0x1365)[0x561d993e5365]
lab5:8062 terminated with signal 11 at PC=560003f0e815 SP=7ffd29e58150.  Backtrace:
./lab5(+0x1815)[0x560003f0e815]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7f9594829d90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x7f9594829e40]
./lab5(+0x1365)[0x560003f0e365]
===================================================================================
BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
PID 8060 RUNNING AT Ubuntu1
EXIT CODE: 9
CLEANING UP REMAINING PROCESSES
YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Killed (signal 9)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions

如何解决?

subC[i * n + j] += subA[i * n + k] * B[k * n + j];

在没有分配内存的情况下解引用B

如果您使用-Wall编译,则会收到有关此错误的通知。

相关内容

  • 没有找到相关文章

最新更新