source: proiecte/pgraph/Code/Roy-Floyd/mpiroyfloyd.c @ 129

Last change on this file since 129 was 129, checked in by (none), 14 years ago
File size: 3.2 KB
Line 
1//Author Antonio-Gabriel Sturzu
2
3#include<mpi.h>
4#include<stdio.h>
5#include<stdlib.h>
6#include<string.h>
7#define lim 100001
8
9int main(int argc,char *argv[])
10{
11        int **m,n,i,j,k,rc,numtasks,rank,dim,next,strip,*line,root,rap;
12        MPI_Status status;
13        double time1,time2;
14       
15        //MPI Initialization
16        rc = MPI_Init(&argc,&argv);
17        if (rc != MPI_SUCCESS) 
18        {
19                printf ("Error starting MPI program. Terminating.\n");
20                MPI_Abort(MPI_COMM_WORLD, rc);
21        }
22        MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
23        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
24       
25        //Reading from file is done by process 0
26        if(rank==0)
27        {       
28                FILE *f=fopen("royfloyd.in","r");
29                fscanf(f,"%i",&n);
30                m=(int **) calloc(n*n,sizeof(int *));
31                for(i=0;i<n;i++)
32                        m[i]=(int *) calloc(n,sizeof(int));
33                for(i=0;i<n;i++)
34                        for(j=0;j<n;j++)
35                        {
36                                fscanf(f,"%i",&m[i][j]);
37                                if(i!=j && m[i][j]==0)
38                                        m[i][j]=lim;
39                        }
40                fclose(f);
41        }               
42
43        //Send n's value to all processes
44        MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
45        line=(int *) calloc(n,sizeof(int));
46        dim=n/numtasks;
47        if(rank==numtasks-1 && n%numtasks!=0)
48                dim=n-dim*(numtasks-1);
49       
50        if(rank>0)
51        {
52                m=(int **) calloc(dim*n,sizeof(int *));
53                for(i=0;i<dim;i++)
54                        m[i]=(int *) calloc(n,sizeof(int));
55        }       
56        MPI_Barrier(MPI_COMM_WORLD);
57
58        //Send matrix portions to all processes
59        if(rank==0)
60        {
61                next = dim;
62                for(k=1;k<numtasks-1;k++) 
63                {
64                        for (i=0;i<dim;i++) 
65                                MPI_Send(m[next+i],n,MPI_INT,k,1,MPI_COMM_WORLD);
66                        next+=dim;
67                }
68                if(numtasks>1)
69                {
70                        if(n%numtasks!=0)
71                                strip=n-dim*(numtasks-1);
72                        else
73                                strip=dim;
74                        for(i=0;i<strip;i++)
75                                MPI_Send(m[next+i],n,MPI_INT,numtasks-1,1,MPI_COMM_WORLD);
76                }       
77        }
78
79        //Receive lines
80        else 
81        {
82                for(i=0;i<dim;i++) 
83                        MPI_Recv(m[i],n,MPI_INT,0,1,MPI_COMM_WORLD,&status);
84        }
85        rap=n/numtasks;
86
87        MPI_Barrier(MPI_COMM_WORLD);
88        time1 = MPI_Wtime();
89       
90        //Distributed Floyd
91        for(k=0;k<n;k++)
92        {
93                root=k/rap;
94                if(root>numtasks-1)
95                        root=numtasks-1;
96                if(root==rank)
97                {
98                        MPI_Bcast(m[k-root*rap],n,MPI_INT,root,MPI_COMM_WORLD);
99                        memmove(line,m[k-root*rap],n*sizeof(int));
100                }
101                else
102                        MPI_Bcast(line,n,MPI_INT,root,MPI_COMM_WORLD);
103               
104                for(i=0;i<dim;i++)
105                        for(j=0;j<n;j++)
106                                if(m[i][k]+line[j]<m[i][j])
107                                        m[i][j]=m[i][k]+line[j];
108                MPI_Barrier(MPI_COMM_WORLD);
109        }
110        MPI_Barrier(MPI_COMM_WORLD);
111        time2=MPI_Wtime();
112        if(rank==0)
113                printf("Time elapsed is %lf\n",time2-time1);
114       
115        //Matrix assembly
116        if(rank!=0)
117                for(i=0;i<dim;i++)
118                        MPI_Send(m[i],n,MPI_INT,0,1,MPI_COMM_WORLD);
119        else
120        {
121                if(numtasks>1)
122                {
123                        next=dim;
124                        for(i=1;i<numtasks-1;i++)
125                        {
126                                for(j=0;j<dim;j++)
127                                        MPI_Recv(m[next+j],n,MPI_INT,i,1,MPI_COMM_WORLD,&status);
128                                next+=dim;
129                        }
130                        for(i=0;i<strip;i++)
131                                MPI_Recv(m[next+i],n,MPI_INT,numtasks-1,1,MPI_COMM_WORLD,&status);
132                }
133        }
134       
135        if(rank==0)
136        {
137                FILE *f=fopen("royfloyd2.out","w");
138                for(i=0;i<n;i++)
139                {
140                        for(j=0;j<n-1;j++)
141                        {
142                                if(m[i][j]==lim)
143                                        m[i][j]=0;
144                                fprintf(f,"%i ",m[i][j]);
145                        }
146                        if(m[i][n-1]==lim)
147                                m[i][n-1]=0;
148                        fprintf(f,"%i\n",m[i][n-1]);
149                }
150                fclose(f);
151                for(i=0;i<n;i++)
152                        free(m[i]);
153        }
154        else
155                for(i=0;i<dim;i++)
156                        free(m[i]);
157        free(m);
158        free(line);
159        MPI_Finalize(); 
160        return 0;
161}
Note: See TracBrowser for help on using the repository browser.