Правильно ли я использую MPI_Scatter и MPI_Gather? - PullRequest
3 голосов
/ 06 апреля 2019

Я пытаюсь выполнить матричное векторное умножение, используя 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
...