rbaian
asked on
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;iCo unt++)
{
for(jCount=0;jCount<c1;jCo unt++)
{
printf("Enter Value for Arr1[%d][%d] :",iCount,jCount);
scanf("%d",&arr1[iCount][j Count]);
}
}
printf("\n\nEnter Values for Vector Matrix ...\n");
for(iCount=0;iCount<r2;iCo unt++)
{
printf("Enter Value for Arr2[%d] :",iCount);
scanf("%d",&arr2[iCount]);
}
ansArr=(int*)sshared(sizeo f(int)*r1, &shmid);
nproc=r1;
// Processes for Each Row Multipication
id=process_fork(nproc);
sum=0;
for(iCount=0;iCount<c1;iCo unt++)
{
sum+=(arr1[id][iCount] * arr2[iCount]);
}
ansArr[id]=sum;
process_join(nproc,id);
printf("Array 1\n");
for(iCount=0;iCount<r1;iCo unt++)
{
for(jCount=0;jCount<c1;jCo unt++)
{
printf("%d\t",arr1[iCount] [jCount]);
}
printf("\n");
}
printf("Array 2 (Vector Matrix) \n");
for(iCount=0;iCount<r1;iCo unt++)
{
printf("%d\n",arr2[iCount] );
}
printf("Matrix-Vector Multipication \n");
for(iCount=0;iCount<r1;iCo unt++)
{
printf("%d\n",ansArr[iCoun t]);
}
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,bu f) !=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,in it_sem_val ue) < 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);
}
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;iCo
{
for(jCount=0;jCount<c1;jCo
{
printf("Enter Value for Arr1[%d][%d] :",iCount,jCount);
scanf("%d",&arr1[iCount][j
}
}
printf("\n\nEnter Values for Vector Matrix ...\n");
for(iCount=0;iCount<r2;iCo
{
printf("Enter Value for Arr2[%d] :",iCount);
scanf("%d",&arr2[iCount]);
}
ansArr=(int*)sshared(sizeo
nproc=r1;
// Processes for Each Row Multipication
id=process_fork(nproc);
sum=0;
for(iCount=0;iCount<c1;iCo
{
sum+=(arr1[id][iCount] * arr2[iCount]);
}
ansArr[id]=sum;
process_join(nproc,id);
printf("Array 1\n");
for(iCount=0;iCount<r1;iCo
{
for(jCount=0;jCount<c1;jCo
{
printf("%d\t",arr1[iCount]
}
printf("\n");
}
printf("Array 2 (Vector Matrix) \n");
for(iCount=0;iCount<r1;iCo
{
printf("%d\n",arr2[iCount]
}
printf("Matrix-Vector Multipication \n");
for(iCount=0;iCount<r1;iCo
{
printf("%d\n",ansArr[iCoun
}
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,bu
{
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,
if(*lok==-1)
{
perror("Error in Semget ...");
exit(1);
}
if(semctl(*lok,0,SETVAL,in
{
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,
{
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);
}
ASKER
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(sizeo f(int)*r1, &shmid);
i tried to change 1&2 but there is error says: neither array nor pointer
i think i need more change here
(1) int *ansArr;
// Multipication Answer Stored Here
(2) ansArr=(int*)sshared(sizeo
i tried to change 1&2 but there is error says: neither array nor pointer
ansArr=(int*)sshared(sizeo f(int)*r1, &shmid);
should change to
ansArr=(int*)sshared(sizeo f(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;iCo unt++) // 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);
should change to
ansArr=(int*)sshared(sizeo
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;iCo
{
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);
ASKER
Kelvin_King
i made change in this part
printf("Matrix-Vector Multipication \n");
for(iCount=0;iCount<r1;iCo unt++)
{
printf("%d\n",ansArr[iCoun t]);
}
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
i made change in this part
printf("Matrix-Vector Multipication \n");
for(iCount=0;iCount<r1;iCo
{
printf("%d\n",ansArr[iCoun
}
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
sorry, i made a mistake in my earlier code:
id=process_fork(nproc);
sum=0;
for(iCount=0;iCount<c2;iCo unt++) // 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.
id=process_fork(nproc);
sum=0;
for(iCount=0;iCount<c2;iCo
{
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.
ASKER
with this:
printf("Matrix-Matrix Multipication \n");
for(iCount=0;iCount<c2;iCo unt++) // 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.
printf("Matrix-Matrix Multipication \n");
for(iCount=0;iCount<c2;iCo
{
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.
try this:
for(iCount=0;iCount<c2;iCo unt++) // for the number of columns in matrix2
{
for(jcount = 0; jCount < r2; jCount++) //for the number of rows in matrix2
{
printf("%d",ansArr[jCount] );
}
}
for(iCount=0;iCount<c2;iCo
{
for(jcount = 0; jCount < r2; jCount++) //for the number of rows in matrix2
{
printf("%d",ansArr[jCount]
}
}
ASKER
still not working
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
remember to initialize the ansArr to 0 first.
ASKER
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
can you explain how the code work in general ..... i want to be sure if i get it correctly
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.
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.
ASKER
thank you ... kelvin king
Glad I could help : )
>>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.