0

I wanna do matrix vector multiplication. The code is compiling but not running. Can anyone please help me out in solving the problem? Thank you in advance.

#include "mpi.h" 
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#define DIM 500

int main(int argc, char *argv[])
{
    int i, j, n=10000; 
    int nlocal;        /* Number of locally stored rows of A */ 
    double *fb;
    double a[DIM * DIM], b[DIM], x[DIM];     /* Will point to a buffer that stores the entire vector b */ 
    int npes, myrank; 
    MPI_Status status; 

    MPI_Init(&argc, &argv);

    /* Get information about the communicator */ 
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    MPI_Comm_size(MPI_COMM_WORLD, &npes);  

    /* Allocate the memory that will store the entire vector b */ 
    fb = (double*)malloc(npes * sizeof(double)); 
    nlocal = n / npes; 

    /* Gather the entire vector b on each processor using MPI's ALLGATHER operation */ 
    MPI_Allgather(b, nlocal, MPI_DOUBLE, fb, nlocal, MPI_DOUBLE, MPI_COMM_WORLD); 

    /* Perform the matrix-vector multiplication involving the locally stored submatrix */ 
    for (i = 0; i < nlocal; i++) { 
        x[i] = 0.0; 
        for (j = 0; j < n; j++) 
            x[i] += a[i * n + j] * fb[j]; 
    } 
    free(fb);
    MPI_Finalize();   
} //end main 

Please help me out in running the code. Thanks.

aki
  • 1
  • 1
  • 6

1 Answers1

2

The issue may come from fb = (double*)malloc(npes * sizeof(double)); which should be fb = (double*)malloc(n * sizeof(double));. Indeed, npes is the number of processes and n is the total length of the vector.

Moreover, the array a is of size 500x500=250000. This is enough to store 25 rows if n=10000... Are you using 400 processes ? If you are using less that 400 processes a[i * n + j] is an attempt to read after the end of the array. It triggers undefined behaviors, such as a segmentation fault.

Last a is a large array and since it is declared as double a[500*500], it is allocated on the stack. Read : Segmentation fault on large array sizes : the best way to go is to use malloc() for a as well, with appropiate size (here nlocal*n).

double *a=malloc(nlocal*n*sizeof(double));
if(a==NULL){fprintf(stderr,"process %d : malloc failed\n",npes);exit(1);}
...
free(a);

n=10000 is rather large. Consider using computed numbers such as nlocal*n for the size of the array a, not default sizes such as DIM. That way, you will be able to debug your code on smaller n and memory will not be wasted.

The same comments apply to b and x allocated as double b[500] and double x[500] while much larger arrays are needed if n=10000. Once again, consider using malloc() with the appropriate number, not a defined value DIM=500 !

double *b=malloc(n*sizeof(double));
if(b==NULL){fprintf(stderr,"process %d : malloc failed\n",npes);exit(1);}
...
free(b);

double *x=malloc(nlocal*sizeof(double));
if(x==NULL){fprintf(stderr,"process %d : malloc failed\n",npes);exit(1);}
...
free(x);

A debugger such as valgrind can detect such problems related to memory management. Try it on your program using a single process !

Community
  • 1
  • 1
francis
  • 9,525
  • 2
  • 25
  • 41