Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (4,48 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 <limits.h>
10
#include <mpi.h>
11

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

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

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

    
27
#define ITERATIONS 1000000000
28

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

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

    
40
   LENGTH total=0;
41

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

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

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

    
52
   return(total);
53

    
54
}
55

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

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

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

    
68
  MPI_Status Stat;
69

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

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

    
79
  if (rank==0) {
80

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

    
89
    printf ("Sizeof int = %lld bytes.\n", (long long)sizeof(int));
90
    printf ("Sizeof long = %lld bytes.\n", (long long)sizeof(long));
91
    printf ("Sizeof long long = %lld bytes.\n", (long long)sizeof(long long));
92

    
93
    printf ("Max int = %u\n", INT_MAX);
94
    printf ("Max long = %ld\n", LONG_MAX);
95
    printf ("Max long long = %lld\n", LLONG_MAX);
96

    
97
    part_iterations=iterations/numtasks+1;
98

    
99
    // Split part of code
100
    for (i=1;i<numtasks;i++) {
101

    
102
#ifdef LONG
103
      rc = MPI_Send(&part_iterations, 1, MPI_LONG_LONG, i, tag, 
104
                    MPI_COMM_WORLD);
105
#else
106
      rc = MPI_Send(&part_iterations, 1, MPI_INT, i, tag, 
107
                    MPI_COMM_WORLD);
108
#endif
109
    }
110
    
111
#ifdef TIME
112
    gettimeofday(&start,(struct timezone *)0);
113
#endif
114

    
115
    insides=MainLoopGlobal(part_iterations,seed_w,seed_z);
116

    
117
#ifdef TIME
118
    gettimeofday(&end,(struct timezone *)0);
119
    useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
120

    
121
      printf("\tOn %i, find %lld inside in %lu useconds.\n",rank,
122
             (long long)insides,useconds);
123
#else
124
      printf("\tOn %i, find %lld inside\n",rank,
125
             (long long)insides);
126

    
127
#endif
128

    
129
    // Join part of code
130
    for (i=1;i<numtasks;i++) {
131
#ifdef LONG
132
      rc = MPI_Recv(&inside[i], 1, MPI_LONG_LONG, i, tag, 
133
                    MPI_COMM_WORLD, &Stat);
134
#else
135
      rc = MPI_Recv(&inside[i], 1, MPI_INT, i, tag, 
136
                    MPI_COMM_WORLD, &Stat);
137
#endif
138
      printf("\tReceive %lu inside from %i\n",(unsigned long)inside[i],i);
139
      insides+=inside[i];
140
    }
141
    
142
    pi=4.*(float)insides/(float)((iterations/numtasks)*numtasks);
143
    
144
    printf("\n\tPi=%.40f\n\twith error %.40f\n\twith %lld iterations\n\n",pi,
145
           fabs(pi-4*atan(1.))/pi,(long long)iterations);
146
  }
147
  else
148
    {
149
      // Receive information from master
150
#ifdef LONG
151
      rc = MPI_Recv(&part_iterations, 1, MPI_LONG_LONG, 0, tag, 
152
                    MPI_COMM_WORLD, &Stat);
153
#else
154
      rc = MPI_Recv(&part_iterations, 1, MPI_INT, 0, tag, 
155
                    MPI_COMM_WORLD, &Stat);
156
#endif
157

    
158
      printf("\tOn %i, receive from master %lld\n",
159
             rank,(long long)part_iterations);
160
      
161
#ifdef TIME
162
      gettimeofday(&start,(struct timezone *)0);
163
#endif
164

    
165
      part_inside=MainLoopGlobal(part_iterations,seed_w,seed_z);
166
      
167
#ifdef TIME
168
    gettimeofday(&end,(struct timezone *)0);
169
    useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
170

    
171
      printf("\tOn %i, find %lld inside in %lu useconds.\n",rank,
172
             (long long)part_inside,useconds);
173
#else
174
      printf("\tOn %i, find %lld inside\n",rank,
175
             (long long)part_inside);
176

    
177
#endif
178

    
179
      rc = MPI_Send(&part_inside, 1, MPI_UNSIGNED_LONG, 0, tag, MPI_COMM_WORLD);
180
    }
181
  
182
  MPI_Finalize();
183

    
184
}