Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'v3_8_x'
[simgrid.git] / teshsuite / smpi / mpich-test / pt2pt / systest.c
1 #include "mpi.h"
2 #include <stdio.h>
3
4 #define MAX2(a,b) (((a)>(b)) ? (a) : (b))
5
6 int  GlobalReadInteger();
7 void Hello();
8 /*
9 void Ring();
10 void Stress();
11 void Globals();
12 */
13
14 int main( int argc, char **argv )
15 {
16
17     int me, option;
18
19     MPI_Init(&argc, &argv);
20     MPI_Comm_rank(MPI_COMM_WORLD,&me);
21
22     fprintf(stderr,"Process %d is alive\n",me);
23
24     while (1) {
25
26         MPI_Barrier(MPI_COMM_WORLD);
27
28       again:
29         if (me == 0) {
30             /* Read user input for action */
31             (void) printf("\nOptions: 0=quit, 1=Hello, 2=Ring, 3=Stress, ");
32             (void) printf("4=Globals : ");
33             (void) fflush(stdout);
34         }
35         option = GlobalReadInteger();
36         if ( (option < 0) || (option > 4) )
37             goto again;
38
39         switch (option) {
40           case 0:
41             MPI_Finalize();
42             return;
43           case 1:
44             Hello();     break;
45           case 2:
46             Ring();      break;
47 /*
48           case 3:
49             Stress();    break;
50           case 4:
51             Globals();   break;
52 */
53           default:
54             fprintf(stderr,"systest: invalid option %d\n", option);   break;
55         }
56     }
57 }
58
59 int GlobalReadInteger()
60 /*
61   Process zero reads an integer from stdin and broadcasts
62   to everyone else
63 */
64 {
65     int me, value, *msg, msg_len, type=999 ,zero=0;
66
67     MPI_Comm_rank(MPI_COMM_WORLD, &me);
68     if (me == 0) {
69         if (scanf("%d", &value) != 1)
70             fprintf(stderr,"failed reading integer value from stdin\n");
71     }
72     MPI_Bcast(&value, 1, MPI_INT, 0, MPI_COMM_WORLD);
73     return value;
74 }
75
76 static void Hello()
77 /*
78   Everyone exchanges a hello message with everyone else.
79   The hello message just comprises the sending and target nodes.
80 */
81 {
82     int nproc, me;
83     int type = 1;
84     int buffer[2], node, length;
85     MPI_Status status;
86
87     MPI_Comm_rank(MPI_COMM_WORLD, &me);
88     MPI_Comm_size(MPI_COMM_WORLD, &nproc);
89
90     if (me == 0) {
91         printf("\nHello test ... show network integrity\n----------\n\n");
92         fflush(stdout);
93     }
94
95     for (node = 0; node<nproc; node++) {
96         if (node != me) {
97             buffer[0] = me;
98             buffer[1] = node;
99             MPI_Send(buffer, 2, MPI_INT, node, type, MPI_COMM_WORLD);
100             MPI_Recv(buffer, 2, MPI_INT, node, type, MPI_COMM_WORLD, &status);
101
102             if ( (buffer[0] != node) || (buffer[1] != me) ) {
103                 (void) fprintf(stderr, "Hello: %d!=%d or %d!=%d\n",
104                                buffer[0], node, buffer[1], me);
105                 printf("Mismatch on hello process ids; node = %d\n", node);
106             }
107
108             printf("Hello from %d to %d\n", me, node);
109             fflush(stdout);
110         }
111     }
112 }
113
114 static void Ring()       /* Time passing a message round a ring */
115 {
116     int nproc, me;
117     MPI_Status status;
118     int nproc = p4_num_total_ids();
119     int type = 4;
120     int left = (me + nproc - 1) % nproc;
121     int right = (me + 1) % nproc;
122     char *buffer, *msg;
123     int start, lenbuf, used, max_len,  msg_len;
124     double rate, us_rate;
125     double start_ustime, end_ustime, used_ustime;
126
127     MPI_Comm_rank(MPI_COMM_WORLD, &me);
128     MPI_Comm_size(MPI_COMM_WORLD, &nproc);
129     left = (me + nproc - 1) % nproc;
130     right = (me + 1) % nproc;
131
132     /* Find out how big a message to use */
133
134     if (me == 0) {
135         (void) printf("\nRing test...time network performance\n---------\n\n");
136         (void) printf("Input maximum message size: ");
137         (void) fflush(stdout);
138     }
139     max_len = GlobalReadInteger();
140     if ( (max_len <= 0) || (max_len >= 4*1024*1024) )
141         max_len = 512*1024;
142     if ( (buffer = malloc((unsigned) max_len)) == (char *) NULL) {
143         printf("process %d could not allocate buffer of size %d\n",me,max_len);
144         MPI_Abort(MPI_COMM_WORLD,7777);
145     }
146
147     lenbuf = 1;
148     while (lenbuf <= max_len) {
149         start_ustime = MPI_Wtime();
150         if (me == 0) {
151             MPI_Send(buffer,lenbuf,MPI_CHAR,left, type,MPI_COMM_WORLD);
152             MPI_Recv(buffer,lenbuf,MPI_CHAR,right,type,MPI_COMM_WORLD,&status);
153         }
154         else {
155             MPI_Recv(buffer,lenbuf,MPI_CHAR,right,type,MPI_COMM_WORLD,&status);
156             MPI_Send(buffer,lenbuf,MPI_CHAR,left, type,MPI_COMM_WORLD);
157         }
158         used_ustime = MPI_Wtime() - start_ustime;
159
160         if (used_ustime > 0)
161             us_rate = 1.0 * (double) (nproc * lenbuf) / (double) used_ustime;
162         else
163             us_rate = 0.0;
164         if (me == 0)
165             printf("len=%d bytes, used= %d us, rate=%f Mbytes/sec\n",
166                    lenbuf, used_ustime, us_rate);
167     
168         lenbuf *= 2;
169     }
170     free(buffer);
171 }
172
173 double ranf()
174 /* Returns ran # uniform in (0,1) ... probably rather bad statistics. */
175 {
176   static unsigned long seed = 54321;
177
178   seed = seed * 1812433253 + 12345;
179   return (seed & 0x7fffffff) * 4.6566128752458e-10;
180 }
181
182 static void RandList(lo, hi, list, n)
183      int lo, hi, *list, n;
184 /*
185   Fill list with n random integers between lo & hi inclusively
186 */
187 {
188   int i, ran;
189   double dran;
190
191   for (i=0; i<n; i++) {
192     dran = ranf();
193     ran = lo + (int) (dran * (double) (hi-lo+1));
194     if (ran < lo)
195       ran = lo;
196     if (ran > hi)
197       ran = hi;
198     list[i] = ran;
199   }
200 }
201
202 static void Stress()
203 /*
204   Stress the system by passing messages between a randomly selected
205   list of nodes
206 */
207 {
208 #define N_LEN 10
209 #ifdef NCUBE
210   /* ncube does not handle msgs larger than 
211      32K at present (see nwrite) */
212   static int len[N_LEN] = {0,1,2,4,8,4096,8192,16384,32768,32768};
213 #else
214   static int len[N_LEN] = {0,1,2,4,8,4096,8192,16384,32768,65536};
215 #endif
216   int me = p4_get_my_id();
217   int nproc = p4_num_total_ids();
218   int zero = 0;
219   int type, lenbuf, i, j, from, to;
220   int *list_i, *list_j, *list_n;
221   char *buffer;
222   int n_stress, mod, *msg, msg_len;
223
224
225   type = 6;
226   if (me == 0) {
227     (void) printf("\nStress test ... randomly exchange messages\n-----------");
228     (void) printf("\n\nInput no. of messages: ");
229     (void) fflush(stdout);
230   }
231   n_stress = GlobalReadInteger();
232   if ( (n_stress <= 0) || (n_stress > 100000) )
233     n_stress = 1000;
234   p4_dprintfl(00,"n_stress=%d\n",n_stress);
235
236   lenbuf = n_stress * sizeof(int);
237
238   if (!(buffer = p4_shmalloc((unsigned) len[N_LEN-1])))
239     p4_error("Stress: failed to allocate buffer", len[N_LEN-1]);
240
241   type = 7;
242   if (me == 0) { /* Make random list of pairs and message lengths */
243     if (!(list_i = (int *) p4_shmalloc((unsigned) lenbuf)))
244       p4_error("Stress: failed to allocate list_i",lenbuf);
245     if (!(list_j = (int *) p4_shmalloc((unsigned) lenbuf)))
246       p4_error("Stress: failed to allocate list_j",lenbuf);
247     if (!(list_n = (int *) p4_shmalloc((unsigned) lenbuf)))
248       p4_error("Stress: failed to allocate list_n",lenbuf);
249
250     RandList((int) 0, nproc-1, list_i, n_stress);
251     RandList((int) 0, nproc-1, list_j, n_stress);
252     RandList((int) 0, N_LEN-1, list_n, n_stress);
253     for (i=0; i<n_stress; i++)
254       list_n[i] = len[list_n[i]];
255     p4_broadcastx(type, (char *) list_i, lenbuf, P4INT);
256     p4_broadcastx(type, (char *) list_j, lenbuf, P4INT);
257     p4_broadcastx(type, (char *) list_n, lenbuf, P4INT);
258   }
259   else {
260     list_i = (int *) NULL;
261     (void) p4_recv(&type, &zero, (char **) &list_i, &msg_len);
262     list_j = (int *) NULL;
263     (void) p4_recv(&type, &zero, (char **) &list_j, &msg_len);
264     list_n = (int *) NULL;
265     (void) p4_recv(&type, &zero, (char **) &list_n, &msg_len);
266   }
267
268   type = 8;
269
270   j = 0;
271   mod = (n_stress-1)/10 + 1;
272   for (i=0; i < n_stress; i++) {
273
274     from   = list_i[i];
275     to     = list_j[i];
276     lenbuf = list_n[i];
277
278     /* P4 can send to self 
279     if (from == to)
280       continue; */
281
282     if ( (me == 0) && (j%mod == 0) ) {
283       (void) printf("Stress: test=%ld: from=%ld, to=%ld, len=%ld\n",
284                     i, from, to, lenbuf);
285       (void) fflush(stdout);
286     }
287
288     j++;  /* Needed when skipping send to self */
289
290     if (from == me)
291       (void) p4_send(type, to, buffer, lenbuf);
292
293     if (to == me) {
294       msg = (int *) NULL;
295       (void) p4_recv(&type, &from, (char **) &msg, &msg_len);
296       p4_msg_free((char *) msg);
297       if (msg_len != lenbuf)
298         p4_error("Stress: invalid message length on receive",lenbuf);
299     }
300   }
301
302   (void) p4_shfree(buffer);
303   if (me == 0) {
304     (void) p4_shfree((char *) list_n);
305     (void) p4_shfree((char *) list_j);
306     (void) p4_shfree((char *) list_i);
307   }
308   else {
309     (void) p4_msg_free((char *) list_n);
310     (void) p4_msg_free((char *) list_j);
311     (void) p4_msg_free((char *) list_i);
312   }
313 }
314
315 static int CompareVectors(n, a, b)
316      int n;
317      double *a, *b;
318 /*
319   Return the no. of differences in two vectors allowing for
320   numerical roundoff.
321 */
322 {
323 #define ABS(a)   (((a)>=0 ) ? (a) : -(a))
324   int nerrs = 0;
325   double diff;
326
327   while (n--) {
328     diff = *a++ - *b++;
329     if (ABS(diff) > 1.0e-8)
330       nerrs++;
331   }
332   
333   return nerrs;
334 }
335
336 static void Globals()
337 /*
338   Test out functioning of the global operations.
339 */
340 {
341   int nproc = p4_num_total_ids();
342   int me = p4_get_my_id();
343   int n, i, start, used, nerrs;
344   double *a, *b, rate;
345
346 #define DO(string, op) \
347   start = p4_clock(); \
348   if (p4_global_op(33, (char *) a, n, sizeof(double), op, P4DBL)) \
349     p4_error("p4_global_op failed",n); \
350   used = p4_clock()-start; \
351   rate = (used>0) ? n/(1.0e+3 * used) : 0.0; \
352   nerrs = CompareVectors(n, a, b); \
353   if (me == 0) \
354     (void) printf("%s, len=%d, used=%d ms, rate=%f Mop/sec, nerrs=%d\n",\
355                    string, n, used, rate, nerrs);
356
357   if (me == 0) {
358     (void) printf("\nGlobal operations test\n----------------------");
359     (void) printf("\n\nInput vector length ");
360     (void) fflush(stdout);
361   }
362   n = GlobalReadInteger();
363   if ( (n < 0) || (n > 1000000) )
364     n = 1000;
365
366   if (!(a = (double *) p4_shmalloc((unsigned) (n*sizeof(double)))))
367     p4_error("failed to create work space (a)",n);
368   if (!(b = (double *) p4_shmalloc((unsigned) (n*sizeof(double)))))
369     p4_error("failed to create work space (b)",n);
370
371   /* Summation */
372
373   for (i=0; i<n; i++) {
374     a[i] = i+me;
375     b[i] = nproc*i + (nproc*(nproc-1))/2;
376   }
377   DO("Summation", p4_dbl_sum_op);
378
379   /* Maximum */
380
381   for (i=0; i<n; i++) {
382     a[i] = i+me;
383     b[i] = i+nproc-1;
384   }
385   DO("Maximum", p4_dbl_max_op);
386
387   /* Abs Maximum */
388
389   for (i=0; i<n; i++) {
390     a[i] = i+me - n/2;
391     b[i] = MAX2(n/2-i, i+nproc-1-n/2);
392   }
393   DO("Abs Maximum", p4_dbl_absmax_op);
394
395   /* Tidy up */
396
397   p4_shfree((char *) b);
398   p4_shfree((char *) a);
399 }
400
401
402 void synchronize(type)
403      int type;
404 /*
405   Processes block until all have checked in with process 0
406   with a message of specified type .. a barrier.
407 */
408 {
409   int me = p4_get_my_id();
410   int nproc = p4_num_total_ids();
411   int zero = 0;
412   int *msg;
413   int msg_len, node, dummy = type;
414
415   if (me == zero) {
416     for (node=1; node<nproc; node++){       /* Check in */
417       msg = (int *) NULL;
418       if (p4_recv(&type, &node, (char **) &msg, &msg_len))
419         p4_error("synchronize: recv 1 failed", (int) msg);
420       p4_msg_free((char *) msg);
421     }
422     if (p4_broadcast(type, (char *) &dummy, sizeof dummy))
423       p4_error("synchronize: broadcast failed",type);
424   }
425   else {
426     if (p4_send(type, zero, (char *) &me, sizeof me))
427       p4_error("synchronize: send failed", type);
428     msg = (int *) NULL;
429     if (p4_recv(&type, &zero, (char **) &msg, &msg_len))
430       p4_error("synchronize: recv 2 failed", (int) msg);
431     p4_msg_free((char *) msg);
432   }
433 }