Statistiques
| Révision :

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

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