Statistiques
| Révision :

root / Pi / C / MPI / Pi_MPI.c @ 24

Historique | Voir | Annoter | Télécharger (3,8 ko)

1
//
2
// Estimation of Pi using Monte Carlo exploration process
3
// gcc -std=c99 -O3 -o Pi Pi.c -lm 
4
//
5

    
6
#include <math.h>
7
#include <stdio.h>
8
#include <stdlib.h>
9
#include <mpi.h>
10

    
11
#ifdef TIME
12
#include <sys/time.h>
13
#endif
14

    
15
// Marsaglia RNG very simple implementation
16
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
17
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
18
#define MWC   (znew+wnew)
19
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
20
#define CONG  (jcong=69069*jcong+1234567)
21
#define KISS  ((MWC^CONG)+SHR3)
22

    
23
#define MWCfp MWC * 2.328306435454494e-10f
24
#define KISSfp KISS * 2.328306435454494e-10f
25

    
26
#define ITERATIONS 1000000000
27

    
28
#ifdef LONG
29
#define LENGTH unsigned long
30
#else
31
#define LENGTH unsigned int
32
#endif
33

    
34
LENGTH MainLoopGlobal(LENGTH iterations,unsigned int seed_w,unsigned int seed_z)
35
{
36
   unsigned int z=seed_z;
37
   unsigned int w=seed_w;
38

    
39
   unsigned  long total=0;
40

    
41
   for (LENGTH i=0;i<iterations;i++) {
42

    
43
      float x=MWCfp ;
44
      float y=MWCfp ;
45

    
46
      // Matching test
47
      int inside=((x*x+y*y) < 1.0f) ? 1:0;
48
      total+=inside;
49
   }
50

    
51
   return(total);
52

    
53
}
54

    
55
int main(int argc, char *argv[]) {
56

    
57
  unsigned int seed_w=10,seed_z=10;
58
  LENGTH iterations=ITERATIONS,inside[1024],insides,part_inside,part_iterations;
59
  int numtasks,rank,rc,tag=1,i;
60
  float pi;
61

    
62
#ifdef TIME
63
  struct timeval start,end;
64
  long int useconds;
65
#endif
66

    
67
  MPI_Status Stat;
68

    
69
  rc = MPI_Init(&argc,&argv);
70
  if (rc != MPI_SUCCESS) {
71
    printf ("Error starting MPI program. Terminating.\n");
72
    MPI_Abort(MPI_COMM_WORLD, rc);
73
  }
74

    
75
  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
76
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
77

    
78
  if (rank==0) {
79

    
80
    if (argc > 1) {
81
      iterations=(LENGTH)atol(argv[1]);
82
    }
83
    else {
84
      printf("\n\tPi : Estimate Pi with Monte Carlo exploration\n\n");
85
      printf("\t\t#1 : number of iterations (default 1 billion)\n\n");
86
    }
87

    
88
    part_iterations=iterations/numtasks+1;
89
    // Split part of code
90
    for (i=1;i<numtasks;i++) {
91
      rc = MPI_Send(&part_iterations, 1, MPI_UNSIGNED_LONG, i, tag, 
92
                    MPI_COMM_WORLD);
93
    }
94
    
95
#ifdef TIME
96
    gettimeofday(&start,(struct timezone *)0);
97
#endif
98

    
99
    insides=MainLoopGlobal(part_iterations,seed_w,seed_z);
100

    
101
#ifdef TIME
102
    gettimeofday(&end,(struct timezone *)0);
103
    useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
104

    
105
      printf("\tOn %i, find %lu inside in %lu useconds.\n",rank,
106
             (unsigned long)insides,useconds);
107
#else
108
      printf("\tOn %i, find %lu inside\n",rank,
109
             (unsigned long)insides);
110

    
111
#endif
112

    
113
    // Join part of code
114
    for (i=1;i<numtasks;i++) {
115
      rc = MPI_Recv(&inside[i], 1, MPI_UNSIGNED_LONG, i, tag, 
116
                    MPI_COMM_WORLD, &Stat);
117
      printf("\tReceive %lu inside from %i\n",(unsigned long)inside[i],i);
118
      insides+=inside[i];
119
    }
120
    
121
    pi=4.*(float)insides/(float)((iterations/numtasks)*numtasks);
122
    
123
    printf("\n\tPi=%.40f\n\twith error %.40f\n\twith %lu iterations\n\n",pi,
124
           fabs(pi-4*atan(1.))/pi,(unsigned long)iterations);
125
  }
126
  else
127
    {
128
      // Receive information from master
129
      rc = MPI_Recv(&part_iterations, 1, MPI_UNSIGNED_LONG, 0, tag, 
130
                    MPI_COMM_WORLD, &Stat);
131

    
132
      printf("\tOn %i, receive from master %lu\n",
133
             rank,(unsigned long)part_iterations);
134
      
135
#ifdef TIME
136
      gettimeofday(&start,(struct timezone *)0);
137
#endif
138

    
139
      part_inside=MainLoopGlobal(part_iterations,seed_w,seed_z);
140
      
141
#ifdef TIME
142
    gettimeofday(&end,(struct timezone *)0);
143
    useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
144

    
145
      printf("\tOn %i, find %lu inside in %lu useconds.\n",rank,
146
             (unsigned long)part_inside,useconds);
147
#else
148
      printf("\tOn %i, find %lu inside\n",rank,
149
             (unsigned long)part_inside);
150

    
151
#endif
152

    
153
      rc = MPI_Send(&part_inside, 1, MPI_UNSIGNED_LONG, 0, tag, MPI_COMM_WORLD);
154
    }
155
  
156
  MPI_Finalize();
157

    
158
}