[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
Solved

parallel (Matrix-matrix multiplication)

Posted on 2006-04-08
Medium Priority
2,491 Views
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;

// 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);

}
0
Question by:rbaian
• 8
• 6

LVL 13

Expert Comment

ID: 16409890
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

Author Comment

ID: 16410078
i did all the change that you told me ..... but still matrix vector multiplication

i think i need more change here

(1) int *ansArr;

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

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

0

LVL 13

Expert Comment

ID: 16410263
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

Author Comment

ID: 16414674
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

LVL 13

Expert Comment

ID: 16416338
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

Author Comment

ID: 16422410
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

LVL 13

Expert Comment

ID: 16427076
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

Author Comment

ID: 16433398
still not working
0

LVL 13

Accepted Solution

Kelvin_King earned 1000 total points
ID: 16435520
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

LVL 13

Expert Comment

ID: 16435524
remember to initialize the ansArr to 0 first.

0

Author Comment

ID: 16454684
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

LVL 13

Expert Comment

ID: 16458307
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

Author Comment

ID: 16458912
thank you ... kelvin king
0

LVL 13

Expert Comment

ID: 16458915
Glad I could help : )
0

Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ouâ€¦
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and infâ€¦
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
Suggested Courses
Course of the Month18 days, 2 hours left to enroll