Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

write a matrix multiplication program where the work of calculating the product

ID: 3667941 • Letter: W

Question

write a matrix multiplication program where the work of calculating the product matrix is distributed among multiple threads created using the pthread library. To this end, your program must do the following:

Define two global matrices A[X][Y] & B[Y][Z] to store the two matrices to be multiplied. X and Y must be set using a #define directive.

Define a global matrix C[X][Z] to store the product of matrices A and B. Once again, Z must be set using a #define directive.

Define a pthread function called pthread_multiply to perform the actual matrix multiplication operation (Note: Recall that a pthread function must have a very specific prototype). As a starting point, a regular (non-threaded) function for matrix multiplication, called multiply, has been provided below.

void multiply()

{

          int row,col,inner;

          for (row = 0; row < X; row++) {

                      for (col = 0; col < Z; col++) {

                                  for (inner = 0; inner < Y; inner++) {

                                              C[row][col] += A[row][inner] * B[inner][col];

                                  }

                      }

          }

}

  

The pthread_multiply function you write will essentially be a modification of the above multiply function. Instead of computing the entire product matrix C, the pthread_multiply function will only calculate a subset of rows of the product matrix C. Parameters must be passed to pthread_multiply to tell it which subset of rows to compute (Note: recall that parameter passing to a pthread function is somewhat different because of its specific prototype).

Define a main function and in this function, do the following:

Initialize the matrices A, B and C as follows: each element in A & B must be initialized to the sum of its row and column index and all elements in matrix C must be initialized to zero.

Using a loop, create multiple pthreads to execute the pthread_multiply function (use a #define directive to define the number of threads - this number must be set to more than 2). To each thread, pass appropriate parameters to tell it which subset of rows in the resultant matrix C it is responsible for computing. Each thread must be given an equal share of the resultant matrix as far as possible. For e.g., if you have A[10][10], B[10][10] and if the number of threads is 2 (Note: this is just an example - you must use more than 2 threads), then, thread 1 should be assigned the task of calculating results for rows 0 – 4 of matrix C and thread 2, those for rows 5 – 9. However, if you have A[9][9], B[9][9] and two threads, one of the threads will be assigned a lower number of rows than the other. I.e., in general, the last thread may have less number of rows to compute.

Using a second loop, wait until all the created pthreads have completed, using the pthread_join function.

Once all threads have completed, display the matrix C in an appropriate manner.

Explanation / Answer

# include <stdio.h>
# include <pthread.h>
# include <stdlib.h>

int M1[64][64];
int M2[64][64];
int M3[64][64];

void *pthread_multiply (void *);

struct coord {
   int i; //Row
   int j; //Column
};

int main()
{
   int i,j,l,k=1,count=0;
   //First Matrix
   for (i=0;i<64;i++)
   {
       for (j=0;j<64;j++)
       {
           M1[i][j]=k;
           k++;
       }
   }
  
   //Second Matrix
   i=0,j=0,k=1;
   for (i=0;i<64;i++)
   {
       for (j=0;j<64;j++)
       {
           M2[i][j]=k;
           k++;
       }
   }
   //Multiplying the two Matrices
   i=0,j=0,k=1;
   int sum=0;
   for (i=0;i<64;i++)
   {
       for (j=0;j<64;j++)
       {
           for (l=0;l<8;l++)
           {
           //Assign a row and column for each thread
                struct coord *data = (struct coord *) malloc(sizeof(struct coord));
           data->i = i;
               data->j = j;
                pthread_t tid;       //Thread ID
               pthread_attr_t attr; //Set of thread attributes
                pthread_attr_init(&attr);
                //Creating the thread
                pthread_create(&tid,&attr,pthread_multiply,data);
                //Parents wait for all thread to complete
                pthread_join(tid, NULL);
          
           }
          
       }
   }
   printf(" Displaying multiplied matrices ");
       i,j=0;
       for (i=0;i<64;i++)
       {
           for(j=0;j<64;j++)
           {              
               printf("%d",M3[i][j]);
               printf(" ");
           }
       printf(" ");
       }
   return 0;
}

void *pthread_multiply(void *para)
{
   struct coord *data = para;
   int num, sum = 0;

   //Row multiplied by column
   for(num = 0; num< 64; num++)
   {
        sum += M1[data->i][num] * M2[num][data->j];
   }
   //assign the sum to its coordinate
    M3[data->i][data->j] = sum;
    //Exit the thread
    pthread_exit(0);
}