COMP 3450 Lab Assignment 2: Parallel Matrix-Vector Product with MPI

Verified

Added on  2022/12/29

|8
|1472
|64
Practical Assignment
AI Summary
This assignment involves developing a C program to perform a parallel matrix-vector product using the Message Passing Interface (MPI). The solution begins by including necessary header files such as stdio.h and mpi.h, and then proceeds with initializing MPI and determining the rank and size of the communicator. The core functionality includes reading matrix and vector data from files, distributing matrix rows among processes using MPI_Scatterv, performing the matrix-vector multiplication, and gathering the results using MPI_Gatherv. The program includes timing analysis and graphical representations of performance metrics, comparing the time taken for the computation with different numbers of ranks and matrix sizes. The code also includes error handling for dimension mismatches and demonstrates the use of dynamic memory allocation for efficient handling of large matrices. The assignment aligns with the course requirements of COMP 3450 at Wentworth Institute of Technology, focusing on parallel and distributed computing concepts.
Document Page
Introduction
stdio .h It is header file, for writing the program, we are trying to import some predefined
library function in order to enhance our program. This will make bulk of c standard library
header.
Stdlib stands for standardlibraray,
Stdlib.h for general purpose as a standard library of C or C++ Programming it will indicates
header which has all functions of memory allocation, processs controls and conversion.
MPI full form is Message Passing Library based on the standards in the Programs.
The MPI forum consists of vendors, researchers, developers and users
The MPI program include MPI header file.
#include<mpi.h>
Every MPI program has the following code
#include “mpi.h”
MPI_Init(&arc, &arv);
…..
………….
MPI_Finalize();
MPI_Init, will determine MPI’s international ,variable detected internally square
measure created
MPI_Common_Size is used to identify the size of the Communication Time
MPI_Common_World is did by MPI environment
MPI_Comm_Rank is used to identify sending messages and receiving messages. Rank will
always starts from zero. These ranks will be always used to followup sending and receiving
messages
MPI_Finalize is used to clean MPI things. Further after cleaning up will not find any MPI
here.
Next thing will go to vector
Vector matrix multiplication indicates, row by column vector, when performing this
operation number of rows should be having that many columns to perform multiplication
matrix .
Idea of a matrix and we have row and column with the variable names is using MPI with
vector matrix multiplication. If not mpi.h in your system add mpi.h in the INCLUDE folder.
Also this is the clear understanding program which is practically done
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
Below program was done in C Compiler
For your information there is not much difference between c and c++
Number of Ranks vs Time:
#include<stdio.h>
#include<stdlib.h>
#include<mpi.h>
void multi(int Count,float *Sum,float Vec[],float Data[],int Column)
{
int i=0,j=0,k=0;
while(i<Count)
{
Sum[i] = 0;
for(j=0;j<Column;j++)
{
Sum[i] = Sum[i] + Data[k] * Vec[j];
k++;
}
i++;
}
}
int main(int arc,char *arv[]){
int rank,size, *sendcount,*displace,*reccount;
MPI_INIT(&arc,&arv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Status status;
FILE *fp;
Document Page
char c;
int i,j,k=0,count=0,row=0,column=0;
float n=0,*sum,*rec_data,*data,*vec;
sendcount = (int*)calloc(sizeof(int),size);
reccount = (int*)calloc(sizeof(int),size);
displace = (int*)calloc(sizeof(int),size);
if(rank==0)
{
fp=fopen("matrix.txt","r");
while(fscanf(fp,"%f",&n)!=-1)
{
c=fgetc(fp);
if(c=='\n'){ row=row+1; }
count++;
}
column=count/row;
printf("Row=%d column=%d proc=%d\n",row,column,size);
float mat[row][column];
fseek( fp, 0, SEEK_SET );
data = (float*)calloc(sizeof(float),row*column);
vec = (float*)calloc(sizeof(float),column);
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
fscanf(fp,"%f",&mat[i][j]);
data[k] = mat[i][j];
k++;
Document Page
}
}
fclose(fp);
fp = fopen("vector.txt","r");
count = 0;
while(fscanf(fp,"%f",&n)!=-1){ count++; }
printf("length of vector = %d\n",count);
if(column!=count) { printf("Dimensions do not match.\nCode Terminated");
MPI_Abort(MPI_COMM_WORLD,0); }
fseek( fp, 0, SEEK_SET );
for(i=0;i<column;i++)
{
fscanf(fp,"%f",&vec[i]);
}
fclose(fp);
count=0;
while(1)
{
for(i=0;i<size;i++)
{
sendcount[i] = sendcount[i]+1;
count++;
if(count==row) break;
}
if(count==row) break;
}
for(i=1;i<size;i++)
{
displace[i] = displace[i-1] + sendcount[i-1]*column;
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
sendcount[i-1] = sendcount[i-1] * column;
}
sendcount[size-1] = sendcount[size-1] * column;
for(i=0;i<size;i++)
printf("sendcout=%d disp=%d\n",sendcount[i],displace[i]);
}
MPI_Bcast(&row,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&column,1,MPI_INT,0,MPI_COMM_WORLD);
if(rank!=0)
{
//data=(float*)calloc(sizeof(float),row*column);
vec = (float *)malloc(sizeof(float) * column);
}
MPI_Bcast(vec,column,MPI_FLOAT,0,MPI_COMM_WORLD);
MPI_Bcast(sendcount,size,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(displace,size,MPI_INT,0,MPI_COMM_WORLD);
rec_data=(float*)calloc(sizeof(float),sendcount[rank]);
MPI_Scatterv(data,sendcount,displace,MPI_FLOAT,rec_data,sendcount[rank],MPI_FLOAT,0,
MPI_COMM_WORLD);
count=sendcount[rank]/column;
sum=(float*)calloc(sizeof(float),count);
multi(count,sum,vec,rec_data,column);
float *result=(float *)calloc(sizeof(float),row);
int disp[size];
disp[0]=0;
reccount[0]=sendcount[0]/column;
for(i = 1; i<size; i++)
{
disp[i] = disp[i-1] + sendcount[i-1]/column;
Document Page
reccount[i]=sendcount[i]/column;
}
MPI_Gatherv(sum,count,MPI_FLOAT,result,reccount,disp,MPI_FLOAT,0,MPI_COMM_WORL
D);
If(rank==0)
{ printf("\nMatrix Vector Multiplication is:\n");
for(i=0; i<row; i++)
{
printf("%.3f\n",result(i]);
}
}
free(vec);
free(sum);
free(sendcount);
free(displace);
free(reccount);
free(rec_data);
MPI_Finalize();
return 0;
}
Below graphs are build using Python
In the below graph you will see the details of maximum matrix dimension the is used is 3
Number of ranks [1,2,3]
Time [1,1,2]
Import matplotlib.pyplot as plts
NoOfRanks = [1,2,3]
Time = [1,1,2]
plts.plot(NoOfRanks,Time)
plts.xlabel('x-axis')
plts.ylabel('y-axis')
Document Page
plts.title('Rank Vs Time Graph')
plts.show()
Communication Time [1,1,2]
Matrix Size [1,2,3]
import matplotlib.pyplot as plt
CommunicationTime = [12,2,3]
MatrixSize = [23,1,2]
plt.plot(CommunicationTime, MatrixSize)
plt.xlabel(‘x-axis’)
plt.ylabel(‘y-axis’)
plt.title('Communication Time Vs MatrixSize')
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
plt.show()
chevron_up_icon
1 out of 8
circle_padding
hide_on_mobile
zoom_out_icon
[object Object]