Statistiques
| Révision :

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

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

1 9 equemene
//
2 9 equemene
// Estimation of Pi using Monte Carlo exploration process
3 9 equemene
// gcc -std=c99 -O3 -o Pi Pi.c -lm
4 9 equemene
//
5 9 equemene
6 9 equemene
#include <math.h>
7 9 equemene
#include <stdio.h>
8 9 equemene
#include <stdlib.h>
9 9 equemene
#include <mpi.h>
10 9 equemene
11 23 equemene
#ifdef TIME
12 23 equemene
#include <sys/time.h>
13 23 equemene
#endif
14 23 equemene
15 9 equemene
// Marsaglia RNG very simple implementation
16 9 equemene
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
17 9 equemene
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
18 9 equemene
#define MWC   (znew+wnew)
19 9 equemene
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
20 9 equemene
#define CONG  (jcong=69069*jcong+1234567)
21 9 equemene
#define KISS  ((MWC^CONG)+SHR3)
22 9 equemene
23 9 equemene
#define MWCfp MWC * 2.328306435454494e-10f
24 9 equemene
#define KISSfp KISS * 2.328306435454494e-10f
25 9 equemene
26 9 equemene
#define ITERATIONS 1000000000
27 9 equemene
28 9 equemene
#ifdef LONG
29 9 equemene
#define LENGTH unsigned long
30 9 equemene
#else
31 9 equemene
#define LENGTH unsigned int
32 9 equemene
#endif
33 9 equemene
34 9 equemene
LENGTH MainLoopGlobal(LENGTH iterations,unsigned int seed_w,unsigned int seed_z)
35 9 equemene
{
36 9 equemene
   unsigned int z=seed_z;
37 9 equemene
   unsigned int w=seed_w;
38 9 equemene
39 9 equemene
   unsigned  long total=0;
40 9 equemene
41 9 equemene
   for (LENGTH i=0;i<iterations;i++) {
42 9 equemene
43 9 equemene
      float x=MWCfp ;
44 9 equemene
      float y=MWCfp ;
45 9 equemene
46 9 equemene
      // Matching test
47 9 equemene
      int inside=((x*x+y*y) < 1.0f) ? 1:0;
48 9 equemene
      total+=inside;
49 9 equemene
   }
50 9 equemene
51 9 equemene
   return(total);
52 9 equemene
53 9 equemene
}
54 9 equemene
55 9 equemene
int main(int argc, char *argv[]) {
56 9 equemene
57 9 equemene
  unsigned int seed_w=10,seed_z=10;
58 9 equemene
  LENGTH iterations=ITERATIONS,inside[1024],insides,part_inside,part_iterations;
59 9 equemene
  int numtasks,rank,rc,tag=1,i;
60 9 equemene
  float pi;
61 9 equemene
62 23 equemene
#ifdef TIME
63 23 equemene
  struct timeval start,end;
64 23 equemene
  long int useconds;
65 23 equemene
#endif
66 23 equemene
67 9 equemene
  MPI_Status Stat;
68 9 equemene
69 9 equemene
  rc = MPI_Init(&argc,&argv);
70 9 equemene
  if (rc != MPI_SUCCESS) {
71 9 equemene
    printf ("Error starting MPI program. Terminating.\n");
72 9 equemene
    MPI_Abort(MPI_COMM_WORLD, rc);
73 9 equemene
  }
74 9 equemene
75 9 equemene
  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
76 9 equemene
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
77 9 equemene
78 9 equemene
  if (rank==0) {
79 9 equemene
80 9 equemene
    if (argc > 1) {
81 9 equemene
      iterations=(LENGTH)atol(argv[1]);
82 9 equemene
    }
83 9 equemene
    else {
84 9 equemene
      printf("\n\tPi : Estimate Pi with Monte Carlo exploration\n\n");
85 9 equemene
      printf("\t\t#1 : number of iterations (default 1 billion)\n\n");
86 9 equemene
    }
87 9 equemene
88 23 equemene
    part_iterations=iterations/numtasks+1;
89 9 equemene
    // Split part of code
90 9 equemene
    for (i=1;i<numtasks;i++) {
91 9 equemene
      rc = MPI_Send(&part_iterations, 1, MPI_UNSIGNED_LONG, i, tag,
92 9 equemene
                    MPI_COMM_WORLD);
93 9 equemene
    }
94 9 equemene
95 23 equemene
#ifdef TIME
96 23 equemene
    gettimeofday(&start,(struct timezone *)0);
97 23 equemene
#endif
98 23 equemene
99 9 equemene
    insides=MainLoopGlobal(part_iterations,seed_w,seed_z);
100 23 equemene
101 23 equemene
#ifdef TIME
102 23 equemene
    gettimeofday(&end,(struct timezone *)0);
103 23 equemene
    useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
104 23 equemene
105 23 equemene
      printf("\tOn %i, find %lu inside in %lu useconds.\n",rank,
106 23 equemene
             (unsigned long)insides,useconds);
107 23 equemene
#else
108 23 equemene
      printf("\tOn %i, find %lu inside\n",rank,
109 23 equemene
             (unsigned long)insides);
110 23 equemene
111 23 equemene
#endif
112 23 equemene
113 9 equemene
    // Join part of code
114 9 equemene
    for (i=1;i<numtasks;i++) {
115 9 equemene
      rc = MPI_Recv(&inside[i], 1, MPI_UNSIGNED_LONG, i, tag,
116 9 equemene
                    MPI_COMM_WORLD, &Stat);
117 9 equemene
      printf("\tReceive %lu inside from %i\n",(unsigned long)inside[i],i);
118 9 equemene
      insides+=inside[i];
119 9 equemene
    }
120 9 equemene
121 9 equemene
    pi=4.*(float)insides/(float)((iterations/numtasks)*numtasks);
122 9 equemene
123 23 equemene
    printf("\n\tPi=%.40f\n\twith error %.40f\n\twith %lu iterations\n\n",pi,
124 23 equemene
           fabs(pi-4*atan(1.))/pi,(unsigned long)iterations);
125 9 equemene
  }
126 9 equemene
  else
127 9 equemene
    {
128 9 equemene
      // Receive information from master
129 9 equemene
      rc = MPI_Recv(&part_iterations, 1, MPI_UNSIGNED_LONG, 0, tag,
130 9 equemene
                    MPI_COMM_WORLD, &Stat);
131 9 equemene
132 9 equemene
      printf("\tOn %i, receive from master %lu\n",
133 9 equemene
             rank,(unsigned long)part_iterations);
134 9 equemene
135 23 equemene
#ifdef TIME
136 23 equemene
      gettimeofday(&start,(struct timezone *)0);
137 23 equemene
#endif
138 23 equemene
139 9 equemene
      part_inside=MainLoopGlobal(part_iterations,seed_w,seed_z);
140 9 equemene
141 23 equemene
#ifdef TIME
142 23 equemene
    gettimeofday(&end,(struct timezone *)0);
143 23 equemene
    useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
144 9 equemene
145 23 equemene
      printf("\tOn %i, find %lu inside in %lu useconds.\n",rank,
146 23 equemene
             (unsigned long)part_inside,useconds);
147 23 equemene
#else
148 23 equemene
      printf("\tOn %i, find %lu inside\n",rank,
149 23 equemene
             (unsigned long)part_inside);
150 23 equemene
151 23 equemene
#endif
152 23 equemene
153 9 equemene
      rc = MPI_Send(&part_inside, 1, MPI_UNSIGNED_LONG, 0, tag, MPI_COMM_WORLD);
154 9 equemene
    }
155 9 equemene
156 9 equemene
  MPI_Finalize();
157 9 equemene
158 9 equemene
}