Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (2,97 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 9 equemene
// Marsaglia RNG very simple implementation
12 9 equemene
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
13 9 equemene
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
14 9 equemene
#define MWC   (znew+wnew)
15 9 equemene
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
16 9 equemene
#define CONG  (jcong=69069*jcong+1234567)
17 9 equemene
#define KISS  ((MWC^CONG)+SHR3)
18 9 equemene
19 9 equemene
#define MWCfp MWC * 2.328306435454494e-10f
20 9 equemene
#define KISSfp KISS * 2.328306435454494e-10f
21 9 equemene
22 9 equemene
#define ITERATIONS 1000000000
23 9 equemene
24 9 equemene
#ifdef LONG
25 9 equemene
#define LENGTH unsigned long
26 9 equemene
#else
27 9 equemene
#define LENGTH unsigned int
28 9 equemene
#endif
29 9 equemene
30 9 equemene
LENGTH MainLoopGlobal(LENGTH iterations,unsigned int seed_w,unsigned int seed_z)
31 9 equemene
{
32 9 equemene
   unsigned int z=seed_z;
33 9 equemene
   unsigned int w=seed_w;
34 9 equemene
35 9 equemene
   unsigned  long total=0;
36 9 equemene
37 9 equemene
   for (LENGTH i=0;i<iterations;i++) {
38 9 equemene
39 9 equemene
      float x=MWCfp ;
40 9 equemene
      float y=MWCfp ;
41 9 equemene
42 9 equemene
      // Matching test
43 9 equemene
      int inside=((x*x+y*y) < 1.0f) ? 1:0;
44 9 equemene
      total+=inside;
45 9 equemene
   }
46 9 equemene
47 9 equemene
   return(total);
48 9 equemene
49 9 equemene
}
50 9 equemene
51 9 equemene
int main(int argc, char *argv[]) {
52 9 equemene
53 9 equemene
  unsigned int seed_w=10,seed_z=10;
54 9 equemene
  LENGTH iterations=ITERATIONS,inside[1024],insides,part_inside,part_iterations;
55 9 equemene
  int numtasks,rank,rc,tag=1,i;
56 9 equemene
  float pi;
57 9 equemene
58 9 equemene
  MPI_Status Stat;
59 9 equemene
60 9 equemene
  rc = MPI_Init(&argc,&argv);
61 9 equemene
  if (rc != MPI_SUCCESS) {
62 9 equemene
    printf ("Error starting MPI program. Terminating.\n");
63 9 equemene
    MPI_Abort(MPI_COMM_WORLD, rc);
64 9 equemene
  }
65 9 equemene
66 9 equemene
  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
67 9 equemene
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
68 9 equemene
69 9 equemene
  if (rank==0) {
70 9 equemene
71 9 equemene
    if (argc > 1) {
72 9 equemene
      iterations=(LENGTH)atol(argv[1]);
73 9 equemene
    }
74 9 equemene
    else {
75 9 equemene
      printf("\n\tPi : Estimate Pi with Monte Carlo exploration\n\n");
76 9 equemene
      printf("\t\t#1 : number of iterations (default 1 billion)\n\n");
77 9 equemene
    }
78 9 equemene
79 9 equemene
    part_iterations=iterations/numtasks;
80 9 equemene
    // Split part of code
81 9 equemene
    for (i=1;i<numtasks;i++) {
82 9 equemene
      rc = MPI_Send(&part_iterations, 1, MPI_UNSIGNED_LONG, i, tag,
83 9 equemene
                    MPI_COMM_WORLD);
84 9 equemene
    }
85 9 equemene
86 9 equemene
    insides=MainLoopGlobal(part_iterations,seed_w,seed_z);
87 9 equemene
88 9 equemene
    // Join part of code
89 9 equemene
    for (i=1;i<numtasks;i++) {
90 9 equemene
      rc = MPI_Recv(&inside[i], 1, MPI_UNSIGNED_LONG, i, tag,
91 9 equemene
                    MPI_COMM_WORLD, &Stat);
92 9 equemene
      printf("\tReceive %lu inside from %i\n",(unsigned long)inside[i],i);
93 9 equemene
      insides+=inside[i];
94 9 equemene
    }
95 9 equemene
96 9 equemene
    pi=4.*(float)insides/(float)((iterations/numtasks)*numtasks);
97 9 equemene
98 9 equemene
    printf("\tPi=%f with error %f and %lu iterations\n\n",pi,
99 9 equemene
           fabs(pi-4*atan(1))/pi,(unsigned long)iterations);
100 9 equemene
  }
101 9 equemene
  else
102 9 equemene
    {
103 9 equemene
      // Receive information from master
104 9 equemene
      rc = MPI_Recv(&part_iterations, 1, MPI_UNSIGNED_LONG, 0, tag,
105 9 equemene
                    MPI_COMM_WORLD, &Stat);
106 9 equemene
107 9 equemene
      printf("\tOn %i, receive from master %lu\n",
108 9 equemene
             rank,(unsigned long)part_iterations);
109 9 equemene
110 9 equemene
      part_inside=MainLoopGlobal(part_iterations,seed_w,seed_z);
111 9 equemene
112 9 equemene
      printf("\tOn %i, find %lu inside\n",rank,(unsigned long)part_inside);
113 9 equemene
114 9 equemene
      rc = MPI_Send(&part_inside, 1, MPI_UNSIGNED_LONG, 0, tag, MPI_COMM_WORLD);
115 9 equemene
    }
116 9 equemene
117 9 equemene
  MPI_Finalize();
118 9 equemene
119 9 equemene
}