source: proiecte/pgraph/Code/Dijkstra/pdikstra.c @ 129

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