Révision 126

Pi/C/MPI/Makefile (revision 126)
5 5
MARSAGLIA=SHR3 CONG MWC KISS
6 6

  
7 7
CC=mpicc.openmpi
8
CFLAGS=-Wall -O3 -std=c99
8
CFLAGS=-Wall -Wno-unused-variable -Wno-sequence-point -O3 -std=c99
9 9
LIBRARY=-lm
10 10

  
11 11
all: $(SOURCE)
Pi/C/MPI/Pi_MPI.c (revision 126)
12 12
#include <stdlib.h>
13 13
#include <limits.h>
14 14
#include <mpi.h>
15
#include <stddef.h>
15 16

  
16
#ifdef TIME
17 17
#include <sys/time.h>
18
#endif
19 18

  
20 19
// Marsaglia RNG very simple implementation
21 20
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
......
27 26

  
28 27
#define MWCfp MWC * 2.328306435454494e-10f
29 28
#define KISSfp KISS * 2.328306435454494e-10f
29
#define SHR3fp SHR3 * 2.328306435454494e-10f
30
#define CONGfp CONG * 2.328306435454494e-10f
30 31

  
31 32
#define ITERATIONS 1000000000
32 33

  
......
36 37
#define LENGTH int
37 38
#endif
38 39

  
40
typedef struct compute_node {
41
        LENGTH inside;
42
        long int useconds;
43
} result;
44

  
39 45
unsigned int rotl(unsigned int value, int shift) {
40 46
    return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift));
41 47
}
......
46 52

  
47 53
LENGTH MainLoopGlobal(LENGTH iterations,unsigned int seed_w,unsigned int seed_z)
48 54
{
55
#if defined TCONG
56
   unsigned int jcong=seed_z;
57
#elif defined TSHR3
58
   unsigned int jsr=seed_w;
59
#elif defined TMWC
49 60
   unsigned int z=seed_z;
50 61
   unsigned int w=seed_w;
62
#elif defined TKISS
63
   unsigned int jcong=seed_z;
64
   unsigned int jsr=seed_w;
65
   unsigned int z=seed_z;
66
   unsigned int w=seed_w;
67
#endif
51 68

  
52
   LENGTH total=0;
69
  LENGTH total=0;
53 70

  
54 71
   for (LENGTH i=0;i<iterations;i++) {
55 72

  
56
      float x=MWCfp ;
57
      float y=MWCfp ;
73
#if defined TINT32
74
    #define THEONE 1073741824
75
    #if defined TCONG
76
        unsigned int x=CONG>>17 ;
77
        unsigned int y=CONG>>17 ;
78
    #elif defined TSHR3
79
        unsigned int x=SHR3>>17 ;
80
        unsigned int y=SHR3>>17 ;
81
    #elif defined TMWC
82
        unsigned int x=MWC>>17 ;
83
        unsigned int y=MWC>>17 ;
84
    #elif defined TKISS
85
        unsigned int x=KISS>>17 ;
86
        unsigned int y=KISS>>17 ;
87
    #endif
88
#elif defined TINT64
89
    #define THEONE 4611686018427387904
90
    #if defined TCONG
91
        unsigned long x=(unsigned long)(CONG>>1) ;
92
        unsigned long y=(unsigned long)(CONG>>1) ;
93
    #elif defined TSHR3
94
        unsigned long x=(unsigned long)(SHR3>>1) ;
95
        unsigned long y=(unsigned long)(SHR3>>1) ;
96
    #elif defined TMWC
97
        unsigned long x=(unsigned long)(MWC>>1) ;
98
        unsigned long y=(unsigned long)(MWC>>1) ;
99
    #elif defined TKISS
100
        unsigned long x=(unsigned long)(KISS>>1) ;
101
        unsigned long y=(unsigned long)(KISS>>1) ;
102
    #endif
103
#elif defined TFP32
104
    #define THEONE 1.0f
105
    #if defined TCONG
106
        float x=CONGfp ;
107
        float y=CONGfp ;
108
    #elif defined TSHR3
109
        float x=SHR3fp ;
110
        float y=SHR3fp ;
111
    #elif defined TMWC
112
        float x=MWCfp ;
113
        float y=MWCfp ;
114
    #elif defined TKISS
115
      float x=KISSfp ;
116
      float y=KISSfp ;
117
    #endif
118
#elif defined TFP64
119
    #define THEONE 1.0f
120
    #if defined TCONG
121
        double x=(double)CONGfp ;
122
        double y=(double)CONGfp ;
123
    #elif defined TSHR3
124
        double x=(double)SHR3fp ;
125
        double y=(double)SHR3fp ;
126
    #elif defined TMWC
127
        double x=(double)MWCfp ;
128
        double y=(double)MWCfp ;
129
    #elif defined TKISS
130
        double x=(double)KISSfp ;
131
        double y=(double)KISSfp ;
132
    #endif
133
#endif
58 134

  
59 135
      // Matching test
60
      int inside=((x*x+y*y) < 1.0f) ? 1:0;
136
      unsigned long inside=((x*x+y*y) < THEONE) ? 1:0;
61 137
      total+=inside;
62 138
   }
63

  
139
  
64 140
   return(total);
65

  
66 141
}
67 142

  
68 143
int main(int argc, char *argv[]) {
69 144

  
70 145
  unsigned int seed_z=362436069,seed_w=52128862;
71
  LENGTH iterations=ITERATIONS,inside[1024],insides,part_inside,part_iterations;
146
  LENGTH iterations=ITERATIONS,inside[8192],insides,part_inside,part_iterations;
72 147
  int numtasks,rank,rc,tag=1,i;
73 148
  float pi;
74 149

  
......
76 151

  
77 152
  gethostname(hostname, sizeof hostname);
78 153

  
79
#ifdef TIME
80 154
  struct timeval start,end;
81 155
  long int useconds;
82
#endif
83 156

  
84 157
  MPI_Status Stat;
85 158

  
......
92 165
  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
93 166
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
94 167

  
168
  const int nitems=2;
169
  int blocklengths[2] = {1,1};
170

  
171
#ifdef LONG
172
  MPI_Datatype types[2] = {MPI_LONG, MPI_LONG};
173
#else
174
  MPI_Datatype types[2] = {MPI_INT, MPI_LONG};
175
#endif
176

  
177
  MPI_Datatype mpi_result_type;
178
  MPI_Aint     offsets[2];
179

  
180
  offsets[0] = offsetof(result, inside);
181
  offsets[1] = offsetof(result, useconds);
182
  
183
  MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_result_type);
184
  MPI_Type_commit(&mpi_result_type);
185
    
95 186
  if (rank==0) {
96 187
    
97 188
    if (argc > 1) {
......
102 193
      printf("\t\t#1 : number of iterations (default 1 billion)\n\n");
103 194
    }
104 195
    
105
    printf ("Sizeof int = %lld bytes.\n", (long long)sizeof(int));
106
    printf ("Sizeof long = %lld bytes.\n", (long long)sizeof(long));
107
    printf ("Sizeof long long = %lld bytes.\n", (long long)sizeof(long long));
196
    printf ("\tSizeof int = %lld bytes.\n", (long long)sizeof(int));
197
    printf ("\tSizeof long = %lld bytes.\n", (long long)sizeof(long));
198
    printf ("\tSizeof long long = %lld bytes.\n", (long long)sizeof(long long));
108 199
    
109
    printf ("Max int = %u\n", INT_MAX);
110
    printf ("Max long = %ld\n", LONG_MAX);
111
    printf ("Max long long = %lld\n", LLONG_MAX);
200
    printf ("\tMax int = %u\n", INT_MAX);
201
    printf ("\tMax long = %ld\n", LONG_MAX);
202
    printf ("\tMax long long = %lld\n\n", LLONG_MAX);
112 203
    
113
    part_iterations=iterations/numtasks+1;
204
    part_iterations=((iterations%numtasks) == 0) ? iterations/numtasks:iterations/numtasks+1 ;
114 205
    
115 206
    // Split part of code
116 207
    for (i=1;i<numtasks;i++) {
......
124 215
#endif
125 216
    }
126 217
    
127
#ifdef TIME
128 218
    gettimeofday(&start,(struct timezone *)0);
129
#endif
130 219
    
131 220
    insides=MainLoopGlobal(part_iterations,seed_w,seed_z);
132 221
    
133
#ifdef TIME
134 222
    gettimeofday(&end,(struct timezone *)0);
135 223
    useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
136 224
    
137
      printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
225
    printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
138 226
	     hostname,rank,(long long)insides,useconds);
139
#else
140
      printf("\tOn %s with rank %i, find %lld inside\n",hostname,rank,
141
	     (long long)insides);
142 227
      
143
#endif
144
      
145 228
    // Join part of code
146 229
      for (i=1;i<numtasks;i++) {
147
#ifdef LONG
148
	rc = MPI_Recv(&inside[i], 1, MPI_LONG_LONG, i, tag, 
230

  
231
	result recv;
232
	
233
	rc = MPI_Recv(&recv, 1, mpi_result_type, i, tag, 
149 234
		      MPI_COMM_WORLD, &Stat);
150
#else
151
	rc = MPI_Recv(&inside[i], 1, MPI_INT, i, tag, 
152
		      MPI_COMM_WORLD, &Stat);
153
#endif
154
	printf("\tReceive %lu inside from rank %i\n",(unsigned long)inside[i],i);
235

  
236
	inside[i]=recv.inside;
237
	useconds=recv.useconds;
238
	
239
	printf("\tReceive from %i, find %lld inside in %lu useconds\n",i,(long long)inside[i],useconds);
240
	
155 241
	insides+=inside[i];
156 242
      }
157 243
      
158
      pi=4.*(float)insides/(float)((iterations/numtasks)*numtasks);
244
      pi=4.*(float)insides/(float)(part_iterations*numtasks);
159 245
      
160 246
      printf("\n\tPi=%.40f\n\twith error %.40f\n\twith %lld iterations\n\n",pi,
161 247
	     fabs(pi-4*atan(1.))/pi,(long long)iterations);
......
172 258
                    MPI_COMM_WORLD, &Stat);
173 259
#endif
174 260
      
175
      printf("\tOn %s with rank %i, receive from master %lld\n",
176
             hostname,rank,(long long)part_iterations);
261
      /*      Not such a good idea to print information... 
262
	      printf("\tOn %s with rank %i, receive from master %lld\n",
263
	      hostname,rank,(long long)part_iterations); */
177 264
      
178
#ifdef TIME
179 265
      gettimeofday(&start,(struct timezone *)0);
180
#endif
181 266

  
182 267
      part_inside=MainLoopGlobal(part_iterations,rotr(seed_w,rank),rotl(seed_z,rank));
183 268
      
184
      
185
#ifdef TIME
186 269
      gettimeofday(&end,(struct timezone *)0);
187 270
      useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
188
      
271

  
272
      /*      
189 273
      printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
190 274
	     hostname,rank,(long long)part_inside,useconds);
191
#else
192
      printf("\tOn %s with rank %i, find %lld inside\n",hostname,rank,
193
	     (long long)part_inside);
194
      
195
#endif
196
      
197
#ifdef LONG
198
      rc = MPI_Send(&part_inside, 1, MPI_LONG_LONG, 0, tag, MPI_COMM_WORLD);
199
#else
200
      rc = MPI_Send(&part_inside, 1, MPI_INT, 0, tag, MPI_COMM_WORLD);
201
#endif
275
      */
202 276

  
277
      result send;
278
      send.inside=part_inside;
279
      send.useconds=useconds;
280

  
281
      rc = MPI_Send(&send, 1, mpi_result_type, 0, tag, MPI_COMM_WORLD);
282

  
203 283
    }
204
  
284

  
285
  MPI_Type_free(&mpi_result_type);  
205 286
  MPI_Finalize();
206
  
207 287
}
Pi/C/MPI/Pi_aMPI.c (revision 126)
1 1
//
2 2
// Estimation of Pi using Monte Carlo exploration process
3
// gcc -std=c99 -O3 -o Pi Pi.c -lm 
3
// gcc -std=c99 -O3 -o Pi_aMPI Pi_aMPI.c -lm 
4 4
// Emmanuel Quemener <emmanuel.quemener@ens-lyon.fr>
5 5

  
6 6
// Needed for gethostname
......
12 12
#include <stdlib.h>
13 13
#include <limits.h>
14 14
#include <mpi.h>
15
#include <stddef.h>
15 16

  
16
#ifdef TIME
17 17
#include <sys/time.h>
18
#endif
19 18

  
20 19
// Marsaglia RNG very simple implementation
21 20
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
......
38 37
#define LENGTH int
39 38
#endif
40 39

  
40
typedef struct compute_node {
41
        LENGTH inside;
42
        long int useconds;
43
} result;
44

  
41 45
unsigned int rotl(unsigned int value, int shift) {
42 46
    return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift));
43 47
}
......
140 144
int main(int argc, char *argv[]) {
141 145

  
142 146
  unsigned int seed_z=362436069,seed_w=52128862;
143
  LENGTH iterations=ITERATIONS,inside[1024],insides,part_inside,part_iterations;
147
  LENGTH iterations=ITERATIONS,inside[8192],insides,part_inside,part_iterations;
144 148
  int numtasks,rank,rc,tag=1,i;
145 149
  float pi;
146 150

  
......
164 168

  
165 169
  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
166 170
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
171
  
172
  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
173
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
167 174

  
175
  const int nitems=2;
176
  int blocklengths[2] = {1,1};
177

  
178
#ifdef LONG
179
  MPI_Datatype types[2] = {MPI_LONG, MPI_LONG};
180
#else
181
  MPI_Datatype types[2] = {MPI_INT, MPI_LONG};
182
#endif
183

  
184
  MPI_Datatype mpi_result_type;
185
  MPI_Aint     offsets[2];
186

  
187
  offsets[0] = offsetof(result, inside);
188
  offsets[1] = offsetof(result, useconds);
189
  
190
  MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_result_type);
191
  MPI_Type_commit(&mpi_result_type);
192

  
168 193
  if (rank==0) {
169 194
    
170 195
    if (argc > 1) {
......
175 200
      printf("\t\t#1 : number of iterations (default 1 billion)\n\n");
176 201
    }
177 202
    
178
    printf ("Sizeof int = %lld bytes.\n", (long long)sizeof(int));
179
    printf ("Sizeof long = %lld bytes.\n", (long long)sizeof(long));
180
    printf ("Sizeof long long = %lld bytes.\n", (long long)sizeof(long long));
203
    printf ("\tSizeof int = %lld bytes.\n", (long long)sizeof(int));
204
    printf ("\tSizeof long = %lld bytes.\n", (long long)sizeof(long));
205
    printf ("\tSizeof long long = %lld bytes.\n", (long long)sizeof(long long));
181 206
    
182
    printf ("Max int = %u\n", INT_MAX);
183
    printf ("Max long = %ld\n", LONG_MAX);
184
    printf ("Max long long = %lld\n", LLONG_MAX);
207
    printf ("\tMax int = %u\n", INT_MAX);
208
    printf ("\tMax long = %ld\n", LONG_MAX);
209
    printf ("\tMax long long = %lld\n", LLONG_MAX);
185 210
    
186
    part_iterations=iterations/numtasks+1;
211
    part_iterations=((iterations%numtasks) == 0) ? iterations/numtasks:iterations/numtasks+1 ;
187 212
    
188 213
    // Split part of code
189 214
    for (i=1;i<numtasks;i++) {
......
200 225
      MPI_Wait(&RequestSend, &Stat);
201 226
    }
202 227
    
203
#ifdef TIME
204 228
    gettimeofday(&start,(struct timezone *)0);
205
#endif
206 229
    
207 230
    insides=MainLoopGlobal(part_iterations,seed_w,seed_z);
208 231
    
209
#ifdef TIME
210 232
    gettimeofday(&end,(struct timezone *)0);
211 233
    useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
212 234
    
213
      printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
235
    printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
214 236
	     hostname,rank,(long long)insides,useconds);
215
#else
216
      printf("\tOn %s with rank %i, find %lld inside\n",hostname,rank,
217
	     (long long)insides);
218 237
      
219
#endif
220
      
221 238
    // Join part of code
222 239
      for (i=1;i<numtasks;i++) {
223
#ifdef LONG
224
	rc = MPI_Irecv(&inside[i], 1, MPI_LONG_LONG, i, tag, 
240

  
241
	result recv;
242
	
243
	rc = MPI_Irecv(&recv, 1, mpi_result_type, i, tag, 
225 244
		      MPI_COMM_WORLD, &RequestRecv2);
226
#else
227
	rc = MPI_Irecv(&inside[i], 1, MPI_INT, i, tag, 
228
		      MPI_COMM_WORLD, &RequestRecv2);
229
#endif
245

  
230 246
	if (numtasks>1) {
231 247
	    MPI_Wait(&RequestRecv2, &Stat);
232 248
	}
233 249
	
234
	printf("\tReceive %lu inside from rank %i\n",(unsigned long)inside[i],i);
250
	inside[i]=recv.inside;
251
	useconds=recv.useconds;
252
	
253
	printf("\tReceive from %i, find %lld inside in %lu useconds\n",i,(long long)inside[i],useconds);
254
	
235 255
	insides+=inside[i];
236 256
      }
237 257
      
238
      pi=4.*(float)insides/(float)((iterations/numtasks)*numtasks);
258
      pi=4.*(float)insides/(float)(part_iterations*numtasks);
239 259
      
240 260
      printf("\n\tPi=%.40f\n\twith error %.40f\n\twith %lld iterations\n\n",pi,
241 261
	     fabs(pi-4*atan(1.))/pi,(long long)iterations);
......
244 264
  else
245 265
    {
246 266
      // Receive information from master
267
      
247 268
#ifdef LONG
248 269
      rc = MPI_Irecv(&part_iterations, 1, MPI_LONG_LONG, 0, tag, 
249 270
                    MPI_COMM_WORLD, &RequestRecv);
......
253 274
#endif
254 275
      MPI_Wait(&RequestRecv, &Stat);
255 276
      
256
      printf("\tOn %s with rank %i, receive from master %lld\n",
257
             hostname,rank,(long long)part_iterations);
277
      /* Not such a good idea to print information... 
278
	 printf("\tOn %s with rank %i, receive from master %lld\n",
279
	 hostname,rank,(long long)part_iterations); */
258 280
      
259
#ifdef TIME
260 281
      gettimeofday(&start,(struct timezone *)0);
261
#endif
262 282

  
263 283
      part_inside=MainLoopGlobal(part_iterations,rotr(seed_w,rank),rotl(seed_z,rank));
264 284
      
265
      
266
#ifdef TIME
267 285
      gettimeofday(&end,(struct timezone *)0);
268 286
      useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
269
      
287

  
288
      /*
270 289
      printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
271 290
	     hostname,rank,(long long)part_inside,useconds);
272
#else
273
      printf("\tOn %s with rank %i, find %lld inside\n",hostname,rank,
274
	     (long long)part_inside);
291
      */
292

  
293
      result send;
294
      send.inside=part_inside;
295
      send.useconds=useconds;      
275 296
      
276
#endif
277
      
278
#ifdef LONG
279
      rc = MPI_Isend(&part_inside, 1, MPI_LONG_LONG, 0, tag, MPI_COMM_WORLD,&RequestSend2);
280
#else
281
      rc = MPI_Isend(&part_inside, 1, MPI_INT, 0, tag, MPI_COMM_WORLD,&RequestSend2);
282
#endif
297
      rc = MPI_Isend(&send, 1, mpi_result_type, 0, tag, MPI_COMM_WORLD,&RequestSend2);
298

  
283 299
      MPI_Wait(&RequestSend2, &Stat);
284 300

  
285 301
    }
286
  
302

  
303
  MPI_Type_free(&mpi_result_type);
287 304
  MPI_Finalize();
288 305
  
289 306
}

Formats disponibles : Unified diff