source: proiecte/pgraph/Code/Prim/papm.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
4#include<stdio.h>
5#include<string.h>
6#include<stdlib.h>
7#include<mpi.h>
8#define inf 1001
9
10int main(int argc,char *argv[])
11{
12        int rc,numtasks,rank,**m,n,*line,dim,next=0,strip,*key,*viz,*prev,minl=0,iminl,ming,iming,costl=0,prod,costg,sup;
13        int i,j,temp;
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("apm2.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        m=(int **) calloc(n*dim,sizeof(int *));
42        for(i=0;i<n;i++)
43                        m[i]=(int *) calloc(dim,sizeof(int));
44        if(rank==0)
45        {
46                line=(int *) calloc(n,sizeof(int));
47                for(i=0;i<n;i++)
48                {
49                        next=dim;
50                        for(j=0;j<n;j++)
51                                fscanf(f,"%i",line+j);
52                        memmove(m[i],line,dim*sizeof(int));
53                        for(j=1;j<numtasks-1;j++)
54                        {
55                                MPI_Send(&line[next],dim,MPI_INT,j,1,MPI_COMM_WORLD);
56                                next+=dim;
57                        }
58                        if(numtasks>1)
59                                MPI_Send(&line[next],n-next,MPI_INT,numtasks-1,1,MPI_COMM_WORLD);
60                }
61        }               
62        else
63                for(i=0;i<n;i++)
64                        MPI_Recv(m[i],dim,MPI_INT,0,1,MPI_COMM_WORLD,&status);
65
66        key=(int *) calloc(dim,sizeof(int));
67        viz=(int *) calloc(dim,sizeof(int));
68        prev=(int *) calloc(dim,sizeof(int));
69
70        MPI_Barrier(MPI_COMM_WORLD);
71        time1=MPI_Wtime();
72        //Initialize the keys
73        if(rank!=0)
74        {
75                for(i=0;i<dim;i++)
76                        key[i]=inf;
77        }
78        else
79        {
80                for(i=1;i<dim;i++)
81                        key[i]=inf;
82                key[0]=0;
83        }
84
85        if(rank!=numtasks-1)
86        {
87                prod=rank*dim;
88                sup=prod+dim;
89        }
90        else
91        {
92                prod=rank*strip;
93                sup=n;
94        }
95        MPI_Barrier(MPI_COMM_WORLD);
96
97        //Distributed Prim's algorithm
98        for(;;)
99        {
100                minl=inf;
101                for(i=0;i<dim;i++)
102                {
103                        if(viz[i]==0 && key[i]<minl)
104                        {
105                                minl=key[i];
106                                iminl=i;
107                        }
108                }
109                //Determine the global minimum value of a key
110                MPI_Allreduce(&minl,&ming,1,MPI_INT,MPI_MIN,MPI_COMM_WORLD);
111                if(ming==inf)
112                        break;
113       
114                if(minl==ming)
115                {
116                        temp=iminl+prod;
117                        MPI_Allreduce(&temp,&iming,1,MPI_INT,MPI_MIN,MPI_COMM_WORLD);
118                }
119                else
120                        MPI_Allreduce(&n,&iming,1,MPI_INT,MPI_MIN,MPI_COMM_WORLD);
121       
122                //If the newest node that will be added to the tree is owned by this process
123                //then marke it as out of the local queue
124               
125                if(iming>=prod && iming<sup)
126                {
127                        viz[iming-prod]=1;
128                        costl+=minl;
129                }
130                for(i=0;i<dim;i++)
131                {
132                        if(m[iming][i]<key[i] && viz[i]==0)
133                        {
134                                key[i]=m[iming][i];
135                                prev[i]=iming;
136                        }
137                }
138                MPI_Barrier(MPI_COMM_WORLD);
139        }
140
141        MPI_Reduce(&costl,&costg,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
142        MPI_Barrier(MPI_COMM_WORLD);
143        time2=MPI_Wtime();
144        if(rank==0)
145                printf("Au trecut %f secunde \n",time2-time1);
146
147        if(rank==0)
148        {
149                printf("Costul minim este %i\n",costg);
150                printf("Muchiile arborelui sunt: \n");
151        }
152        MPI_Barrier(MPI_COMM_WORLD);
153
154        for(i=0;i<dim;i++)
155                        if(i+prod!=0)
156                                printf("%i %i\n",prev[i]+1,i+prod+1);
157        for(i=0;i<n;i++)
158                free(m[i]);
159        free(m);
160        free(key);
161        free(prev);
162        free(viz);
163        if(rank==0)
164                free(line);
165        MPI_Finalize(); 
166        return 0;
167}
Note: See TracBrowser for help on using the repository browser.