Я пытаюсь выполнить матричное векторное умножение, используя MPI_Scatter и MPI_Gather. Я видел другой код, но он не решает конкретную проблему, которая у меня есть.
Моя попытка - выполнить операцию Ax = b, разделив строки матрицы между процессами, вычислив часть b в каждом процессе и собрав их вместе в вектор b в конце. Для простоты я предполагаю, что размеры числа строк делятся на количество процессов. Вот моя попытка
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
void Mat_Vec(int n, int m, double *A, double *x, double **b, int myrank, int p, MPI_Comm comm)
{
double *local_A, *local_b;
int local_n;
int i, j, ii;
MPI_Bcast(&n, 1, MPI_INT, 0, comm);
MPI_Bcast(&m, 1, MPI_INT, 0, comm);
MPI_Bcast(x, m, MPI_DOUBLE, 0, comm);
local_n = n/p;
local_A = (double *) malloc(sizeof(double)*m*local_n);
local_b = (double *) malloc(sizeof(double)*local_n);
MPI_Scatter(A, local_n*m, MPI_DOUBLE, local_A,local_n*m, MPI_DOUBLE, 0, comm);
for (i = 0; i < local_n; i++)
{
ii = i*m;
local_b[i] = 0.0;
for(j=0; j < m; j++)
local_b[i] += local_A[ii+j]*x[j];
}
MPI_Gather(local_b, local_n, MPI_DOUBLE,(*b), local_n, MPI_DOUBLE, 0, comm);
free(local_A);
free(local_b);
}
main(int argc, char* argv[])
{
int n, m, p;
int my_rank;
int i;
double *A, *x, *b;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if (my_rank == 0)
{
printf("Enter the number of rows and columns: ")
n = 4;
m = 4;
A = (double*) malloc(sizeof(double)*n*m);
x = (double*) malloc(sizeof(double)*m);
b = (double*) malloc(sizeof(double)*n);
printf("Enter the matrix row wise \n");
for (i=0; i < n*m; i++)
A[i] = 1.0;
printf("Enter the vector\n");
for (i=0; i < m; i++)
x[i] = 1.0;
}
Mat_Vec(n, m, A, x, &b, my_rank, p, MPI_COMM_WORLD);
if (my_rank == 0)
{
for (i=0; i < n; i++)
printf("%lf\n", b[i]);
free(A); free(x); free(b);
}
MPI_Finalize();
}
Основная функция выделила память, необходимую для всех входов функции matvec. Я продолжаю сталкиваться со следующей ошибкой: завершается сигналом 11. Я полагаю, что это связано с тем, что какой-то процесс пытается получить доступ к памяти, которая не была выделена, но я не вижу, где это будет.
Я использую следующую процедуру:
#!/bin/bash
#SBATCH --job-name=mpi_matvec.c
#SBATCH --time=00:02:00
#SBATCH --output=matvec.%j
#SBATCH --ntasks=2
mpirun ./matvec