Statistiques
| Révision :

root / Pi / C / MPI / Pi_aMPI.c @ 87

Historique | Voir | Annoter | Télécharger (7,57 ko)

1 80 equemene
//
2 80 equemene
// Estimation of Pi using Monte Carlo exploration process
3 80 equemene
// gcc -std=c99 -O3 -o Pi Pi.c -lm
4 80 equemene
// Emmanuel Quemener <emmanuel.quemener@ens-lyon.fr>
5 80 equemene
6 80 equemene
// Needed for gethostname
7 80 equemene
#define _BSD_SOURCE
8 80 equemene
#include <sys/unistd.h>
9 80 equemene
10 80 equemene
#include <math.h>
11 80 equemene
#include <stdio.h>
12 80 equemene
#include <stdlib.h>
13 80 equemene
#include <limits.h>
14 80 equemene
#include <mpi.h>
15 80 equemene
16 80 equemene
#ifdef TIME
17 80 equemene
#include <sys/time.h>
18 80 equemene
#endif
19 80 equemene
20 80 equemene
// Marsaglia RNG very simple implementation
21 80 equemene
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
22 80 equemene
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
23 80 equemene
#define MWC   (znew+wnew)
24 80 equemene
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
25 80 equemene
#define CONG  (jcong=69069*jcong+1234567)
26 80 equemene
#define KISS  ((MWC^CONG)+SHR3)
27 80 equemene
28 80 equemene
#define MWCfp MWC * 2.328306435454494e-10f
29 80 equemene
#define KISSfp KISS * 2.328306435454494e-10f
30 80 equemene
#define SHR3fp SHR3 * 2.328306435454494e-10f
31 80 equemene
#define CONGfp CONG * 2.328306435454494e-10f
32 80 equemene
33 80 equemene
#define ITERATIONS 1000000000
34 80 equemene
35 80 equemene
#ifdef LONG
36 80 equemene
#define LENGTH long long
37 80 equemene
#else
38 80 equemene
#define LENGTH int
39 80 equemene
#endif
40 80 equemene
41 80 equemene
unsigned int rotl(unsigned int value, int shift) {
42 80 equemene
    return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift));
43 80 equemene
}
44 80 equemene
45 80 equemene
unsigned int rotr(unsigned int value, int shift) {
46 80 equemene
    return (value >> shift) | (value << (sizeof(value) * CHAR_BIT - shift));
47 80 equemene
}
48 80 equemene
49 80 equemene
LENGTH MainLoopGlobal(LENGTH iterations,unsigned int seed_w,unsigned int seed_z)
50 80 equemene
{
51 80 equemene
#if defined TCONG
52 80 equemene
   unsigned int jcong=seed_z;
53 80 equemene
#elif defined TSHR3
54 80 equemene
   unsigned int jsr=seed_w;
55 80 equemene
#elif defined TMWC
56 80 equemene
   unsigned int z=seed_z;
57 80 equemene
   unsigned int w=seed_w;
58 80 equemene
#elif defined TKISS
59 80 equemene
   unsigned int jcong=seed_z;
60 80 equemene
   unsigned int jsr=seed_w;
61 80 equemene
   unsigned int z=seed_z;
62 80 equemene
   unsigned int w=seed_w;
63 80 equemene
#endif
64 80 equemene
65 80 equemene
  LENGTH total=0;
66 80 equemene
67 80 equemene
   for (LENGTH i=0;i<iterations;i++) {
68 80 equemene
69 80 equemene
#if defined TINT32
70 80 equemene
    #define THEONE 1073741824
71 80 equemene
    #if defined TCONG
72 80 equemene
        unsigned int x=CONG>>17 ;
73 80 equemene
        unsigned int y=CONG>>17 ;
74 80 equemene
    #elif defined TSHR3
75 80 equemene
        unsigned int x=SHR3>>17 ;
76 80 equemene
        unsigned int y=SHR3>>17 ;
77 80 equemene
    #elif defined TMWC
78 80 equemene
        unsigned int x=MWC>>17 ;
79 80 equemene
        unsigned int y=MWC>>17 ;
80 80 equemene
    #elif defined TKISS
81 80 equemene
        unsigned int x=KISS>>17 ;
82 80 equemene
        unsigned int y=KISS>>17 ;
83 80 equemene
    #endif
84 80 equemene
#elif defined TINT64
85 80 equemene
    #define THEONE 4611686018427387904
86 80 equemene
    #if defined TCONG
87 80 equemene
        unsigned long x=(unsigned long)(CONG>>1) ;
88 80 equemene
        unsigned long y=(unsigned long)(CONG>>1) ;
89 80 equemene
    #elif defined TSHR3
90 80 equemene
        unsigned long x=(unsigned long)(SHR3>>1) ;
91 80 equemene
        unsigned long y=(unsigned long)(SHR3>>1) ;
92 80 equemene
    #elif defined TMWC
93 80 equemene
        unsigned long x=(unsigned long)(MWC>>1) ;
94 80 equemene
        unsigned long y=(unsigned long)(MWC>>1) ;
95 80 equemene
    #elif defined TKISS
96 80 equemene
        unsigned long x=(unsigned long)(KISS>>1) ;
97 80 equemene
        unsigned long y=(unsigned long)(KISS>>1) ;
98 80 equemene
    #endif
99 80 equemene
#elif defined TFP32
100 80 equemene
    #define THEONE 1.0f
101 80 equemene
    #if defined TCONG
102 80 equemene
        float x=CONGfp ;
103 80 equemene
        float y=CONGfp ;
104 80 equemene
    #elif defined TSHR3
105 80 equemene
        float x=SHR3fp ;
106 80 equemene
        float y=SHR3fp ;
107 80 equemene
    #elif defined TMWC
108 80 equemene
        float x=MWCfp ;
109 80 equemene
        float y=MWCfp ;
110 80 equemene
    #elif defined TKISS
111 80 equemene
      float x=KISSfp ;
112 80 equemene
      float y=KISSfp ;
113 80 equemene
    #endif
114 80 equemene
#elif defined TFP64
115 80 equemene
    #define THEONE 1.0f
116 80 equemene
    #if defined TCONG
117 80 equemene
        double x=(double)CONGfp ;
118 80 equemene
        double y=(double)CONGfp ;
119 80 equemene
    #elif defined TSHR3
120 80 equemene
        double x=(double)SHR3fp ;
121 80 equemene
        double y=(double)SHR3fp ;
122 80 equemene
    #elif defined TMWC
123 80 equemene
        double x=(double)MWCfp ;
124 80 equemene
        double y=(double)MWCfp ;
125 80 equemene
    #elif defined TKISS
126 80 equemene
        double x=(double)KISSfp ;
127 80 equemene
        double y=(double)KISSfp ;
128 80 equemene
    #endif
129 80 equemene
#endif
130 80 equemene
131 80 equemene
      // Matching test
132 80 equemene
      unsigned long inside=((x*x+y*y) < THEONE) ? 1:0;
133 80 equemene
      total+=inside;
134 80 equemene
   }
135 80 equemene
136 80 equemene
   return(total);
137 80 equemene
138 80 equemene
}
139 80 equemene
140 80 equemene
int main(int argc, char *argv[]) {
141 80 equemene
142 80 equemene
  unsigned int seed_z=362436069,seed_w=52128862;
143 80 equemene
  LENGTH iterations=ITERATIONS,inside[1024],insides,part_inside,part_iterations;
144 80 equemene
  int numtasks,rank,rc,tag=1,i;
145 80 equemene
  float pi;
146 80 equemene
147 80 equemene
  char hostname[128];
148 80 equemene
149 80 equemene
  gethostname(hostname, sizeof hostname);
150 80 equemene
151 80 equemene
#ifdef TIME
152 80 equemene
  struct timeval start,end;
153 80 equemene
  long int useconds;
154 80 equemene
#endif
155 80 equemene
156 80 equemene
  MPI_Status Stat;
157 80 equemene
  MPI_Request RequestSend, RequestRecv, RequestSend2, RequestRecv2;
158 80 equemene
159 80 equemene
  rc = MPI_Init(&argc,&argv);
160 80 equemene
  if (rc != MPI_SUCCESS) {
161 80 equemene
    printf ("Error starting MPI program. Terminating.\n");
162 80 equemene
    MPI_Abort(MPI_COMM_WORLD, rc);
163 80 equemene
  }
164 80 equemene
165 80 equemene
  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
166 80 equemene
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
167 80 equemene
168 80 equemene
  if (rank==0) {
169 80 equemene
170 80 equemene
    if (argc > 1) {
171 80 equemene
      iterations=(LENGTH)atoll(argv[1]);
172 80 equemene
    }
173 80 equemene
    else {
174 80 equemene
      printf("\n\tPi : Estimate Pi with Monte Carlo exploration\n\n");
175 80 equemene
      printf("\t\t#1 : number of iterations (default 1 billion)\n\n");
176 80 equemene
    }
177 80 equemene
178 80 equemene
    printf ("Sizeof int = %lld bytes.\n", (long long)sizeof(int));
179 80 equemene
    printf ("Sizeof long = %lld bytes.\n", (long long)sizeof(long));
180 80 equemene
    printf ("Sizeof long long = %lld bytes.\n", (long long)sizeof(long long));
181 80 equemene
182 80 equemene
    printf ("Max int = %u\n", INT_MAX);
183 80 equemene
    printf ("Max long = %ld\n", LONG_MAX);
184 80 equemene
    printf ("Max long long = %lld\n", LLONG_MAX);
185 80 equemene
186 80 equemene
    part_iterations=iterations/numtasks+1;
187 80 equemene
188 80 equemene
    // Split part of code
189 80 equemene
    for (i=1;i<numtasks;i++) {
190 80 equemene
191 80 equemene
#ifdef LONG
192 80 equemene
      rc = MPI_Isend(&part_iterations, 1, MPI_LONG_LONG, i, tag,
193 80 equemene
                     MPI_COMM_WORLD,&RequestSend);
194 80 equemene
#else
195 80 equemene
      rc = MPI_Isend(&part_iterations, 1, MPI_INT, i, tag,
196 80 equemene
                     MPI_COMM_WORLD,&RequestSend);
197 80 equemene
#endif
198 80 equemene
    }
199 87 equemene
    if (numtasks>1) {
200 87 equemene
      MPI_Wait(&RequestSend, &Stat);
201 87 equemene
    }
202 80 equemene
203 80 equemene
#ifdef TIME
204 80 equemene
    gettimeofday(&start,(struct timezone *)0);
205 80 equemene
#endif
206 80 equemene
207 80 equemene
    insides=MainLoopGlobal(part_iterations,seed_w,seed_z);
208 80 equemene
209 80 equemene
#ifdef TIME
210 80 equemene
    gettimeofday(&end,(struct timezone *)0);
211 80 equemene
    useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
212 80 equemene
213 80 equemene
      printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
214 80 equemene
             hostname,rank,(long long)insides,useconds);
215 80 equemene
#else
216 80 equemene
      printf("\tOn %s with rank %i, find %lld inside\n",hostname,rank,
217 80 equemene
             (long long)insides);
218 80 equemene
219 80 equemene
#endif
220 80 equemene
221 80 equemene
    // Join part of code
222 80 equemene
      for (i=1;i<numtasks;i++) {
223 80 equemene
#ifdef LONG
224 80 equemene
        rc = MPI_Irecv(&inside[i], 1, MPI_LONG_LONG, i, tag,
225 80 equemene
                      MPI_COMM_WORLD, &RequestRecv2);
226 80 equemene
#else
227 80 equemene
        rc = MPI_Irecv(&inside[i], 1, MPI_INT, i, tag,
228 80 equemene
                      MPI_COMM_WORLD, &RequestRecv2);
229 80 equemene
#endif
230 87 equemene
        if (numtasks>1) {
231 87 equemene
            MPI_Wait(&RequestRecv2, &Stat);
232 87 equemene
        }
233 80 equemene
234 80 equemene
        printf("\tReceive %lu inside from rank %i\n",(unsigned long)inside[i],i);
235 80 equemene
        insides+=inside[i];
236 80 equemene
      }
237 80 equemene
238 80 equemene
      pi=4.*(float)insides/(float)((iterations/numtasks)*numtasks);
239 80 equemene
240 80 equemene
      printf("\n\tPi=%.40f\n\twith error %.40f\n\twith %lld iterations\n\n",pi,
241 80 equemene
             fabs(pi-4*atan(1.))/pi,(long long)iterations);
242 80 equemene
243 80 equemene
  }
244 80 equemene
  else
245 80 equemene
    {
246 80 equemene
      // Receive information from master
247 80 equemene
#ifdef LONG
248 80 equemene
      rc = MPI_Irecv(&part_iterations, 1, MPI_LONG_LONG, 0, tag,
249 80 equemene
                    MPI_COMM_WORLD, &RequestRecv);
250 80 equemene
#else
251 80 equemene
      rc = MPI_Irecv(&part_iterations, 1, MPI_INT, 0, tag,
252 80 equemene
                    MPI_COMM_WORLD, &RequestRecv);
253 80 equemene
#endif
254 80 equemene
      MPI_Wait(&RequestRecv, &Stat);
255 80 equemene
256 80 equemene
      printf("\tOn %s with rank %i, receive from master %lld\n",
257 80 equemene
             hostname,rank,(long long)part_iterations);
258 80 equemene
259 80 equemene
#ifdef TIME
260 80 equemene
      gettimeofday(&start,(struct timezone *)0);
261 80 equemene
#endif
262 80 equemene
263 80 equemene
      part_inside=MainLoopGlobal(part_iterations,rotr(seed_w,rank),rotl(seed_z,rank));
264 80 equemene
265 80 equemene
266 80 equemene
#ifdef TIME
267 80 equemene
      gettimeofday(&end,(struct timezone *)0);
268 80 equemene
      useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
269 80 equemene
270 80 equemene
      printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
271 80 equemene
             hostname,rank,(long long)part_inside,useconds);
272 80 equemene
#else
273 80 equemene
      printf("\tOn %s with rank %i, find %lld inside\n",hostname,rank,
274 80 equemene
             (long long)part_inside);
275 80 equemene
276 80 equemene
#endif
277 80 equemene
278 80 equemene
#ifdef LONG
279 80 equemene
      rc = MPI_Isend(&part_inside, 1, MPI_LONG_LONG, 0, tag, MPI_COMM_WORLD,&RequestSend2);
280 80 equemene
#else
281 80 equemene
      rc = MPI_Isend(&part_inside, 1, MPI_INT, 0, tag, MPI_COMM_WORLD,&RequestSend2);
282 80 equemene
#endif
283 80 equemene
      MPI_Wait(&RequestSend2, &Stat);
284 80 equemene
285 80 equemene
    }
286 80 equemene
287 80 equemene
  MPI_Finalize();
288 80 equemene
289 80 equemene
}