• C

parallel (Matrix-matrix multiplication)

i have this code which is matrix-vector multiplication
i want to change it to Matrix-matrix multiplication

what change should i make?
if you have the code .... it is better.


--------------------------------------------
# include <sys/stdio.h>

# include <sys/types.h>

# include <sys/shm.h>

# include <sys/sem.h>

# include <sys/ipc.h>

# include "forkjoin.h"

# include "sharedlib.h"

# include "spinlock.h"



int main()
{

     int arr1[10][10];
  // Matrix Array

     int arr2[10];
      // Vector Array - Singular Column Matrix

     
     int *ansArr;
        // Multipication Answer Stored Here

                  // It need to be shared
     
             
     int shmid;
        // For ansArr

     
     int r1,c1;
         // Number of Rows and Columns of First Matrix

     int r2,c2=1;
       // Number of Rows and Columns of Second Matrix

     
     int iCount,jCount;

     
     int id;
            // Stores Process ID

     int nproc;
         // Number of Processes

     
     int sum;

     
     printf("Enter Number of Rows of First Matrix :");


     scanf("%d",&r1);

     
     printf("Enter Number of Columns of First Matrix :");

     scanf("%d",&c1);


     printf("Enter Number of Rows of Second Matrix :");

     scanf("%d",&r2);


     
     if(c1!=r2)

     {

          printf("Matrix Multipication is not Possible ...");

          exit(1);

     }

     

     
     // Initialize an Array    
     
     printf("\n\nEnter Values for Matrix ...\n");

     for(iCount=0;iCount<r1;iCount++)

     {

          for(jCount=0;jCount<c1;jCount++)

          {

          printf("Enter Value for Arr1[%d][%d] :",iCount,jCount);

               scanf("%d",&arr1[iCount][jCount]);

          }

     }
     
     printf("\n\nEnter Values for Vector Matrix ...\n");

     for(iCount=0;iCount<r2;iCount++)

     {

          printf("Enter Value for Arr2[%d] :",iCount);

          scanf("%d",&arr2[iCount]);

     }


     ansArr=(int*)sshared(sizeof(int)*r1,&shmid);

     
     nproc=r1;
     // Processes for Each Row Multipication

     
     id=process_fork(nproc);
     sum=0;

     for(iCount=0;iCount<c1;iCount++)

     {

          sum+=(arr1[id][iCount] * arr2[iCount]);

     }
     ansArr[id]=sum;
     
     process_join(nproc,id);

     
     printf("Array 1\n");

     
     for(iCount=0;iCount<r1;iCount++)

     {
          for(jCount=0;jCount<c1;jCount++)

          {

               printf("%d\t",arr1[iCount][jCount]);

          }
     
     printf("\n");

     }


     printf("Array 2 (Vector Matrix) \n");

     for(iCount=0;iCount<r1;iCount++)
     
{
          printf("%d\n",arr2[iCount]);

     }


     
     printf("Matrix-Vector Multipication \n");

     for(iCount=0;iCount<r1;iCount++)

     {

          printf("%d\n",ansArr[iCount]);

     }
     


     cleanup_memory(&shmid);
     
     
     return 0;

}
-----------------------------------------------------

/*
create and remove shared memory block
*/
void *sshared (int size,int size, int *shmid)
{


     *shmid=shmget ( IPC_PRIVATE, size,0666 | IPC_CREAT);

     
if (*shmid < 0)


     {


          printf("Error, cannot share memory");

          exit(0);

     }

              return shmat(*shmid,0,0);

  }




void cleanup_memory(int *shmid)

{

     struct shmid_ds *buf;


     if (shmctl(*shmid,IPC_RMID,buf) !=0)


     {

          printf("Error, cannot free memory");

          exit(0);
     }

}
------------------------------------------------
*    
      for locking the critical region
*/

void spin_lock_init(int *lok)

{
     int init_sem_value=1;
     *lok=semget(IPC_PRIVATE,1,(0600 | IPC_CREAT));
     
     if(*lok==-1)
     {
          perror("Error in Semget ...");
          exit(1);
     }
     
     if(semctl(*lok,0,SETVAL,init_sem_value) < 0)
     {
          perror("Error in Semctl ...");
          exit(1);
     }

}

void spin_lock(int *lok)
{
     struct sembuf sembuffer,*sops;
     sops= &sembuffer;
     sops->sem_num=0;
     sops->sem_op=-1;
     sops->sem_flg=0;
     
     if(semop(*lok,sops,1) < 0)
     {          
          perror("semop lock Error ...");
          exit(1);
     }    

}
void spin_unlock(int *lok)
{
     struct sembuf sembuffer,*sops;
     sops=&sembuffer;
     sops->sem_num=0;
     sops->sem_op=1;
     sops->sem_flg=0;
     
     if(semop(*lok,sops,1) < 0)
     {
          perror("semop Unlock Error ...");
          exit(1);
     }
}

void cleanup_semaphore(int *lok)
{
     if(semctl(*lok,1,IPC_RMID,0)  < 0)
     {
          perror("cleaning");
     }
}
-----------------------------------------------------

/*    
      process creation and process joining
*/



int process_fork(int newproc)
{


     int i;

     for(i=1;i<newproc;i++)

     {


          if(fork()==0)


               return i;


     }


     return 0;


}



int process_join(int newproc,int id)


{


     int i;

     if(id==0)

     {


          for(i=1;i<newproc;i++)

               wait(0);

     }

     else


          exit(0);

}
rbaianAsked:
Who is Participating?
 
Kelvin_KingCommented:
Ok, sorry for that. I gave you the wrong code for multiplying the matrices.

try this:

        int i,j,k;
 
      for(i=0;i<c2;i++)
            for(j=0;j<r2;j++)
                  ansArr[(id * c2) + i] += arr1[id][j] * arr2[j][i];


0
 
Kelvin_KingCommented:
for matrix X matrix multiplication you need to change a few things:

>>int arr2[10];
      // Vector Array - Singular Column Matrix

change to arr2[10][10];

>>int r2,c2=1;
       // Number of Rows and Columns of Second Matrix

change to int r2, c2;

and add one more line :

 printf("Enter Number of Columnss of Second Matrix :");

     scanf("%d",&c2);

That should help get you started. Anothre thing is, I don't think you should fix the array size to 10 x 10 at the begining.
You should initialize the array after you read in the rows and columns from the user. That'll make your program more robust.
0
 
rbaianAuthor Commented:
i did all the change that you told me ..... but still matrix vector multiplication

i think i need more change here

(1) int *ansArr;
        // Multipication Answer Stored Here

(2) ansArr=(int*)sshared(sizeof(int)*r1,&shmid);

i tried to change 1&2 but there is error says: neither array nor pointer

0
WEBINAR: 10 Easy Ways to Lose a Password

Join us on June 27th at 8 am PDT to learn about the methods that hackers use to lift real, working credentials from even the most security-savvy employees. We'll cover the importance of multi-factor authentication and how these solutions can better protect your business!

 
Kelvin_KingCommented:
ansArr=(int*)sshared(sizeof(int)*r1,&shmid);

should change to

ansArr=(int*)sshared(sizeof(int)*r1* c2,&shmid);

the ans matrix will have the same number of rows as the first matrix and numbe rof columns as the second matrix.


And there's more changes down the line.

Currently, each process handles only row, which corresponds to only 1 slot in the Answer array,

this time, each process has to handle all the columns for his row in the answer array. Since your array is an int pointer, you'll need to do some thing like this:

id=process_fork(nproc);
     sum=0;

     for(iCount=0;iCount<c2;iCount++) // for the number of columns in matrix2
     {
        for(jcount = 0; jCount < r2; jCount++)  //for the number of rows in matrix2
       {
          sum+=(arr1[id][jCount] * arr2[jCount][iCount]);
       }
     ansArr[(id * c2) +  iCount ]=sum;
     }

     process_join(nproc,id);
0
 
rbaianAuthor Commented:
Kelvin_King
i made change in this part

printf("Matrix-Vector Multipication \n");

     for(iCount=0;iCount<r1;iCount++)

     {

          printf("%d\n",ansArr[iCount]);

     }
     



i added another for statment and i used ansArr[(id * c2) +  iCount ] in printf but i got wrong result

can you explain  ansArr[(id * c2) +  iCount ]
is it to increase the space of the  ansArr

0
 
Kelvin_KingCommented:
sorry, i made a mistake in my earlier code:

id=process_fork(nproc);
     sum=0;

     for(iCount=0;iCount<c2;iCount++) // for the number of columns in matrix2
     {
        for(jcount = 0; jCount < r2; jCount++)  //for the number of rows in matrix2
       {
          sum+=(arr1[id][jCount] * arr2[jCount][iCount]);
       }
     ansArr[(id * c2) +  iCount ]=sum;
     sum = 0; // see if it works now
     }

     process_join(nproc,id);

>> can you explain  ansArr[(id * c2) +  iCount ]

Basically, what I'm trying to do, is access each row in the ans matrix.

Since id represents the ith row, so to access i,j in the particular matrix. I multiply id by the number of columns in each row. So for example, if id = 3:  Then 3 * c2 will give me the first column in the 3rd row of the matrix, and then (3 * c2) + iCount will give me the next column and so on.

hope this is clearer.
0
 
rbaianAuthor Commented:
with this:
printf("Matrix-Matrix Multipication \n");

for(iCount=0;iCount<c2;iCount++) // for the number of columns in matrix2
     {
        for(jcount = 0; jCount < r2; jCount++)  //for the number of rows in matrix2
              {
                   printf("%d",ansArr[(id * c2) +  iCount ]);
            }
    }
-----------------------------------------------------------------
i tried  to multiply two of 2X2 matrices first one is  r1=1 1 & r2= 1 1 and  second matrix is r1=2 2 & r2= 2 2  the result : r1= 4 4 & r2= 8 8 which is wrong.

 
0
 
Kelvin_KingCommented:
try this:

for(iCount=0;iCount<c2;iCount++) // for the number of columns in matrix2
     {
        for(jcount = 0; jCount < r2; jCount++)  //for the number of rows in matrix2
              {
                   printf("%d",ansArr[jCount]);
            }
    }
0
 
rbaianAuthor Commented:
still not working
0
 
Kelvin_KingCommented:
remember to initialize the ansArr to 0 first.

0
 
rbaianAuthor Commented:
Kelvin king it is working now but my last question.......

can you explain how the code work in general ..... i want to be sure if i get it correctly
0
 
Kelvin_KingCommented:
Glad to hear you got it working : )

Well, basically each process (id) will compute the resultant matrix for that row it's assigned to. Eg, process 0 will handle row 0, process 1 will handle row 1 etc.

So what the code is doing,  is it takes i,j meaning the number of columns in matrix 2 and number of rows in matrix 1, and computes the resultant row in the ans matrix for that process.

Is this clearer now ? Feel free to ask if you are unsure of anything.
0
 
rbaianAuthor Commented:
thank you ... kelvin king
0
 
Kelvin_KingCommented:
Glad I could help : )
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.