Matrix-Vector Multiplication MPI C Source Code

Here’s my first task for MPI Programming. Create a matrix-vector multiplication program using Message Passing Interface. Let’s go directly to the source code and we can discuss it later if you want.

First, MPI with C language commonly use “mpi.h” and you still can use standard C library.

#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "math.h"

#include "mpi.h"

Now, we need to define the size of matrices, A as [AROW x ACOL] and B as [ACOL x 1] so the result let’s call it matrix C [AROW x 1]. Because the row of B must be equals with column of A and the result matrix C has row = AROW and single column. MAX_VALUE is the constant for defining maximum value of random number for matrices elements value.

#define AROW 3
#define ACOL 2

#define MAX_VALUE 10

proc_map() function is the function to map the each task to which process to do it.


/* Process mapping function */
int proc_map(int i, int size)
{
	size = size - 1;
	int r = (int) ceil( (double)AROW / (double)size);
	int proc = i / r;
	return proc + 1;
}

Now this is the full program source code listing.

int main(int argc, char** argv)
{
	int size, rank;
	MPI_Status Stat;

	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &size);
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);

	if (rank == 0)
	{
		int a[AROW][ACOL];
		int b[ACOL];
		int c[AROW];

		/* Generating Random Values for A & B Array*/
		srand(time(NULL));
		for (int i=0;i<AROW;i++)
		{
			for (int j=0;j<ACOL;j++)
			{
				if (i==0) b[j] = rand() % MAX_VALUE;
				a[i][j] = rand() % MAX_VALUE;
			}
		}

		/* Printing the Matrix*/

		printf("Matrix A :n");
		for (int i=0;i<AROW;i++)
		{
			for (int j=0;j<ACOL;j++)
			{
				printf("%3d ", a[i][j]);
			}
			printf("n");
		}
		printf("nMatrix B :n");
		for (int i=0;i<ACOL;i++)
		{
			printf("%3d ", b[i]);
		}
		printf("nn");

		/* (1) Sending B Values to other processes */
		for (int j=1;j<size;j++)
		{
			MPI_Send(b, ACOL, MPI_INTEGER, j, 99, MPI_COMM_WORLD);
		}

		/* (2) Sending Required A Values to specific process */
		for (int i=0;i<AROW;i++)
		{
			int processor = proc_map(i, size);
			MPI_Send(a[i], ACOL, MPI_INTEGER, processor, (100*(i+1)), MPI_COMM_WORLD);
		}

		/* (3) Gathering the result from other processes*/
		for (int i=0;i<AROW;i++)
		{
			int source_process = proc_map(i, size);
			MPI_Recv(&c[i], 1, MPI_INTEGER, source_process, i, MPI_COMM_WORLD, &Stat);
			printf("P%d : c[%d]t= %dn", rank, i, c[i]);
		}
	}
	else
	{
		int b[ACOL];

		/* (1) Each process get B Values from Master */
		MPI_Recv(b, ACOL, MPI_INTEGER, 0, 99, MPI_COMM_WORLD, &Stat);

		/* (2) Get Required A Values from Master then Compute the result */
		for (int i=0;i<AROW;i++)
		{
			int processor = proc_map(i, size);
			if (rank == processor)
			{
				int buffer[ACOL];
				MPI_Recv(buffer, ACOL, MPI_INTEGER, 0, (100*(i+1)), MPI_COMM_WORLD, &Stat);
				int sum = 0;
				for (int j=0;j<ACOL;j++)
				{
					sum = sum + (buffer[j] * b[j] );
				}
				MPI_Send(&sum, 1, MPI_INTEGER, 0, i, MPI_COMM_WORLD);
			}
		}
	}

	MPI_Finalize();
	return 0;
}

3 Thoughts on “Matrix-Vector Multiplication MPI C Source Code

  1. Khalid Hasanov on January 4, 2012 at 11:43 pm said:

    Thanks for your program. Unfortunately there some minor errors: 

    In C you should use MPI_INT instead of MPI_INTEGER. MPI_INTEGER is used in Fortran. This mistake causes to “Null Datatype pointer” in MPI_Send and MPI_Recv.

  2. Madaicol on May 27, 2015 at 12:30 am said:

    There is another error. In the line 69 it’s necesary use proc instead of processor.

Leave a Reply

Your email address will not be published. Required fields are marked *

Post Navigation