Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Free memory.
[simgrid.git] / teshsuite / smpi / mpich3-test / pt2pt / mprobe.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *  (C) 2012 by Argonne National Laboratory.
4  *      See COPYRIGHT in top-level directory.
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "mpi.h"
11 #include "mpitest.h"
12
13 /* assert-like macro that bumps the err count and emits a message */
14 #define check(x_)                                                                 \
15     do {                                                                          \
16         if (!(x_)) {                                                              \
17             ++errs;                                                               \
18             if (errs < 10) {                                                      \
19                 fprintf(stderr, "check failed: (%s), line %d\n", #x_, __LINE__); \
20             }                                                                     \
21         }                                                                         \
22     } while (0)
23
24 #define LARGE_DIM 512
25 #define LARGE_SZ (LARGE_DIM * LARGE_DIM)
26
27 int main(int argc, char **argv)
28 {
29     int errs = 0;
30     int found, completed;
31     int rank, size;
32     int *sendbuf = NULL, *recvbuf = NULL;
33     int count, i;
34     MPI_Message msg;
35     MPI_Request rreq;
36     MPI_Status s1, s2;
37     MPI_Datatype vectype;
38
39     MPI_Init(&argc, &argv);
40
41     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
42     MPI_Comm_size(MPI_COMM_WORLD, &size);
43
44     if (size < 2) {
45         printf("this test requires at least 2 processes\n");
46         MPI_Abort(MPI_COMM_WORLD, 1);
47     }
48
49     /* all processes besides ranks 0 & 1 aren't used by this test */
50     if (rank >= 2) {
51         goto epilogue;
52     }
53
54     sendbuf = (int *) malloc(LARGE_SZ * sizeof(int));
55     recvbuf = (int *) malloc(LARGE_SZ * sizeof(int));
56     if (sendbuf == NULL || recvbuf == NULL) {
57         printf("Error in memory allocation\n");
58         MPI_Abort(MPI_COMM_WORLD, 1);
59     }
60
61     /* test 0: simple send & mprobe+mrecv */
62     if (rank == 0) {
63         sendbuf[0] = 0xdeadbeef;
64         sendbuf[1] = 0xfeedface;
65         MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
66     }
67     else {
68         memset(&s1, 0xab, sizeof(MPI_Status));
69         memset(&s2, 0xab, sizeof(MPI_Status));
70         /* the error field should remain unmodified */
71         s1.MPI_ERROR = MPI_ERR_DIMS;
72         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
73
74         msg = MPI_MESSAGE_NULL;
75         MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
76         check(s1.MPI_SOURCE == 0);
77         check(s1.MPI_TAG == 5);
78         check(s1.MPI_ERROR == MPI_ERR_DIMS);
79         check(msg != MPI_MESSAGE_NULL);
80
81         count = -1;
82         MPI_Get_count(&s1, MPI_INT, &count);
83         check(count == 2);
84
85         recvbuf[0] = 0x01234567;
86         recvbuf[1] = 0x89abcdef;
87         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
88         check(recvbuf[0] == 0xdeadbeef);
89         check(recvbuf[1] == 0xfeedface);
90         check(s2.MPI_SOURCE == 0);
91         check(s2.MPI_TAG == 5);
92         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
93         check(msg == MPI_MESSAGE_NULL);
94     }
95
96     /* test 1: simple send & mprobe+imrecv */
97     if (rank == 0) {
98         sendbuf[0] = 0xdeadbeef;
99         sendbuf[1] = 0xfeedface;
100         MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
101     }
102     else {
103         memset(&s1, 0xab, sizeof(MPI_Status));
104         memset(&s2, 0xab, sizeof(MPI_Status));
105         /* the error field should remain unmodified */
106         s1.MPI_ERROR = MPI_ERR_DIMS;
107         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
108
109         msg = MPI_MESSAGE_NULL;
110         MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
111         check(s1.MPI_SOURCE == 0);
112         check(s1.MPI_TAG == 5);
113         check(s1.MPI_ERROR == MPI_ERR_DIMS);
114         check(msg != MPI_MESSAGE_NULL);
115
116         count = -1;
117         MPI_Get_count(&s1, MPI_INT, &count);
118         check(count == 2);
119
120         rreq = MPI_REQUEST_NULL;
121         recvbuf[0] = 0x01234567;
122         recvbuf[1] = 0x89abcdef;
123         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
124         check(rreq != MPI_REQUEST_NULL);
125         MPI_Wait(&rreq, &s2);
126         check(recvbuf[0] == 0xdeadbeef);
127         check(recvbuf[1] == 0xfeedface);
128         check(s2.MPI_SOURCE == 0);
129         check(s2.MPI_TAG == 5);
130         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
131         check(msg == MPI_MESSAGE_NULL);
132     }
133
134     /* test 2: simple send & improbe+mrecv */
135     if (rank == 0) {
136         sendbuf[0] = 0xdeadbeef;
137         sendbuf[1] = 0xfeedface;
138         MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
139     }
140     else {
141         memset(&s1, 0xab, sizeof(MPI_Status));
142         memset(&s2, 0xab, sizeof(MPI_Status));
143         /* the error field should remain unmodified */
144         s1.MPI_ERROR = MPI_ERR_DIMS;
145         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
146
147         msg = MPI_MESSAGE_NULL;
148         do {
149             check(msg == MPI_MESSAGE_NULL);
150             MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
151         } while (!found);
152         check(msg != MPI_MESSAGE_NULL);
153         check(s1.MPI_SOURCE == 0);
154         check(s1.MPI_TAG == 5);
155         check(s1.MPI_ERROR == MPI_ERR_DIMS);
156
157         count = -1;
158         MPI_Get_count(&s1, MPI_INT, &count);
159         check(count == 2);
160
161         recvbuf[0] = 0x01234567;
162         recvbuf[1] = 0x89abcdef;
163         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
164         check(recvbuf[0] == 0xdeadbeef);
165         check(recvbuf[1] == 0xfeedface);
166         check(s2.MPI_SOURCE == 0);
167         check(s2.MPI_TAG == 5);
168         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
169         check(msg == MPI_MESSAGE_NULL);
170     }
171
172     /* test 3: simple send & improbe+imrecv */
173     if (rank == 0) {
174         sendbuf[0] = 0xdeadbeef;
175         sendbuf[1] = 0xfeedface;
176         MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
177     }
178     else {
179         memset(&s1, 0xab, sizeof(MPI_Status));
180         memset(&s2, 0xab, sizeof(MPI_Status));
181         /* the error field should remain unmodified */
182         s1.MPI_ERROR = MPI_ERR_DIMS;
183         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
184
185         msg = MPI_MESSAGE_NULL;
186         do {
187             check(msg == MPI_MESSAGE_NULL);
188             MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
189         } while (!found);
190         check(msg != MPI_MESSAGE_NULL);
191         check(s1.MPI_SOURCE == 0);
192         check(s1.MPI_TAG == 5);
193         check(s1.MPI_ERROR == MPI_ERR_DIMS);
194
195         count = -1;
196         MPI_Get_count(&s1, MPI_INT, &count);
197         check(count == 2);
198
199         rreq = MPI_REQUEST_NULL;
200         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
201         check(rreq != MPI_REQUEST_NULL);
202         MPI_Wait(&rreq, &s2);
203         check(recvbuf[0] == 0xdeadbeef);
204         check(recvbuf[1] == 0xfeedface);
205         check(s2.MPI_SOURCE == 0);
206         check(s2.MPI_TAG == 5);
207         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
208         check(msg == MPI_MESSAGE_NULL);
209     }
210
211     /* test 4: mprobe+mrecv with MPI_PROC_NULL */
212     {
213         memset(&s1, 0xab, sizeof(MPI_Status));
214         memset(&s2, 0xab, sizeof(MPI_Status));
215         /* the error field should remain unmodified */
216         s1.MPI_ERROR = MPI_ERR_DIMS;
217         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
218
219         msg = MPI_MESSAGE_NULL;
220         MPI_Mprobe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &msg, &s1);
221         check(s1.MPI_SOURCE == MPI_PROC_NULL);
222         check(s1.MPI_TAG == MPI_ANY_TAG);
223         check(s1.MPI_ERROR == MPI_ERR_DIMS);
224         check(msg == MPI_MESSAGE_NO_PROC);
225
226         count = -1;
227         MPI_Get_count(&s1, MPI_INT, &count);
228         check(count == 0);
229
230         recvbuf[0] = 0x01234567;
231         recvbuf[1] = 0x89abcdef;
232         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
233         /* recvbuf should remain unmodified */
234         check(recvbuf[0] == 0x01234567);
235         check(recvbuf[1] == 0x89abcdef);
236         /* should get back "proc null status" */
237         check(s2.MPI_SOURCE == MPI_PROC_NULL);
238         check(s2.MPI_TAG == MPI_ANY_TAG);
239         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
240         check(msg == MPI_MESSAGE_NULL);
241         count = -1;
242         MPI_Get_count(&s2, MPI_INT, &count);
243         check(count == 0);
244     }
245
246     /* test 5: mprobe+imrecv with MPI_PROC_NULL */
247     {
248         memset(&s1, 0xab, sizeof(MPI_Status));
249         memset(&s2, 0xab, sizeof(MPI_Status));
250         /* the error field should remain unmodified */
251         s1.MPI_ERROR = MPI_ERR_DIMS;
252         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
253
254         msg = MPI_MESSAGE_NULL;
255         MPI_Mprobe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &msg, &s1);
256         check(s1.MPI_SOURCE == MPI_PROC_NULL);
257         check(s1.MPI_TAG == MPI_ANY_TAG);
258         check(s1.MPI_ERROR == MPI_ERR_DIMS);
259         check(msg == MPI_MESSAGE_NO_PROC);
260         count = -1;
261         MPI_Get_count(&s1, MPI_INT, &count);
262         check(count == 0);
263
264         rreq = MPI_REQUEST_NULL;
265         recvbuf[0] = 0x01234567;
266         recvbuf[1] = 0x89abcdef;
267         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
268         check(rreq != MPI_REQUEST_NULL);
269         completed = 0;
270         MPI_Test(&rreq, &completed, &s2);       /* single test should always succeed */
271         check(completed);
272         /* recvbuf should remain unmodified */
273         check(recvbuf[0] == 0x01234567);
274         check(recvbuf[1] == 0x89abcdef);
275         /* should get back "proc null status" */
276         check(s2.MPI_SOURCE == MPI_PROC_NULL);
277         check(s2.MPI_TAG == MPI_ANY_TAG);
278         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
279         check(msg == MPI_MESSAGE_NULL);
280         count = -1;
281         MPI_Get_count(&s2, MPI_INT, &count);
282         check(count == 0);
283     }
284
285     /* test 6: improbe+mrecv with MPI_PROC_NULL */
286     {
287         memset(&s1, 0xab, sizeof(MPI_Status));
288         memset(&s2, 0xab, sizeof(MPI_Status));
289         /* the error field should remain unmodified */
290         s1.MPI_ERROR = MPI_ERR_DIMS;
291         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
292
293         msg = MPI_MESSAGE_NULL;
294         found = 0;
295         MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
296         check(found);
297         check(msg == MPI_MESSAGE_NO_PROC);
298         check(s1.MPI_SOURCE == MPI_PROC_NULL);
299         check(s1.MPI_TAG == MPI_ANY_TAG);
300         check(s1.MPI_ERROR == MPI_ERR_DIMS);
301         count = -1;
302         MPI_Get_count(&s1, MPI_INT, &count);
303         check(count == 0);
304
305         recvbuf[0] = 0x01234567;
306         recvbuf[1] = 0x89abcdef;
307         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
308         /* recvbuf should remain unmodified */
309         check(recvbuf[0] == 0x01234567);
310         check(recvbuf[1] == 0x89abcdef);
311         /* should get back "proc null status" */
312         check(s2.MPI_SOURCE == MPI_PROC_NULL);
313         check(s2.MPI_TAG == MPI_ANY_TAG);
314         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
315         check(msg == MPI_MESSAGE_NULL);
316         count = -1;
317         MPI_Get_count(&s2, MPI_INT, &count);
318         check(count == 0);
319     }
320
321     /* test 7: improbe+imrecv */
322     {
323         memset(&s1, 0xab, sizeof(MPI_Status));
324         memset(&s2, 0xab, sizeof(MPI_Status));
325         /* the error field should remain unmodified */
326         s1.MPI_ERROR = MPI_ERR_DIMS;
327         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
328
329         msg = MPI_MESSAGE_NULL;
330         MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
331         check(found);
332         check(msg == MPI_MESSAGE_NO_PROC);
333         check(s1.MPI_SOURCE == MPI_PROC_NULL);
334         check(s1.MPI_TAG == MPI_ANY_TAG);
335         check(s1.MPI_ERROR == MPI_ERR_DIMS);
336         count = -1;
337         MPI_Get_count(&s1, MPI_INT, &count);
338         check(count == 0);
339
340         rreq = MPI_REQUEST_NULL;
341         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
342         check(rreq != MPI_REQUEST_NULL);
343         completed = 0;
344         MPI_Test(&rreq, &completed, &s2);       /* single test should always succeed */
345         check(completed);
346         /* recvbuf should remain unmodified */
347         check(recvbuf[0] == 0x01234567);
348         check(recvbuf[1] == 0x89abcdef);
349         /* should get back "proc null status" */
350         check(s2.MPI_SOURCE == MPI_PROC_NULL);
351         check(s2.MPI_TAG == MPI_ANY_TAG);
352         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
353         check(msg == MPI_MESSAGE_NULL);
354         count = -1;
355         MPI_Get_count(&s2, MPI_INT, &count);
356         check(count == 0);
357     }
358
359     /* test 8: simple ssend & mprobe+mrecv */
360     if (rank == 0) {
361         sendbuf[0] = 0xdeadbeef;
362         sendbuf[1] = 0xfeedface;
363         MPI_Ssend(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
364     }
365     else {
366         memset(&s1, 0xab, sizeof(MPI_Status));
367         memset(&s2, 0xab, sizeof(MPI_Status));
368         /* the error field should remain unmodified */
369         s1.MPI_ERROR = MPI_ERR_DIMS;
370         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
371
372         msg = MPI_MESSAGE_NULL;
373         MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
374         check(s1.MPI_SOURCE == 0);
375         check(s1.MPI_TAG == 5);
376         check(s1.MPI_ERROR == MPI_ERR_DIMS);
377         check(msg != MPI_MESSAGE_NULL);
378
379         count = -1;
380         MPI_Get_count(&s1, MPI_INT, &count);
381         check(count == 2);
382
383         recvbuf[0] = 0x01234567;
384         recvbuf[1] = 0x89abcdef;
385         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
386         check(recvbuf[0] == 0xdeadbeef);
387         check(recvbuf[1] == 0xfeedface);
388         check(s2.MPI_SOURCE == 0);
389         check(s2.MPI_TAG == 5);
390         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
391         check(msg == MPI_MESSAGE_NULL);
392     }
393
394     /* test 9: mprobe+mrecv LARGE */
395     if (rank == 0) {
396         for (i = 0; i < LARGE_SZ; i++)
397             sendbuf[i] = i;
398         MPI_Send(sendbuf, LARGE_SZ, MPI_INT, 1, 5, MPI_COMM_WORLD);
399     }
400     else {
401         memset(&s1, 0xab, sizeof(MPI_Status));
402         memset(&s2, 0xab, sizeof(MPI_Status));
403         /* the error field should remain unmodified */
404         s1.MPI_ERROR = MPI_ERR_DIMS;
405         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
406
407         msg = MPI_MESSAGE_NULL;
408         MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
409         check(s1.MPI_SOURCE == 0);
410         check(s1.MPI_TAG == 5);
411         check(s1.MPI_ERROR == MPI_ERR_DIMS);
412         check(msg != MPI_MESSAGE_NULL);
413
414         count = -1;
415         MPI_Get_count(&s1, MPI_INT, &count);
416         check(count == LARGE_SZ);
417
418         memset(recvbuf, 0xFF, LARGE_SZ * sizeof(int));
419         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
420         for (i = 0; i < LARGE_SZ; i++)
421             check(recvbuf[i] == i);
422         check(s2.MPI_SOURCE == 0);
423         check(s2.MPI_TAG == 5);
424         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
425         check(msg == MPI_MESSAGE_NULL);
426     }
427
428     /* test 10: mprobe+mrecv noncontiguous datatype */
429     MPI_Type_vector(2, 1, 4, MPI_INT, &vectype);
430     MPI_Type_commit(&vectype);
431     if (rank == 0) {
432         memset(sendbuf, 0, 8 * sizeof(int));
433         sendbuf[0] = 0xdeadbeef;
434         sendbuf[4] = 0xfeedface;
435         MPI_Send(sendbuf, 1, vectype, 1, 5, MPI_COMM_WORLD);
436     }
437     else {
438         memset(&s1, 0xab, sizeof(MPI_Status));
439         memset(&s2, 0xab, sizeof(MPI_Status));
440         /* the error field should remain unmodified */
441         s1.MPI_ERROR = MPI_ERR_DIMS;
442         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
443
444         msg = MPI_MESSAGE_NULL;
445         MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
446         check(s1.MPI_SOURCE == 0);
447         check(s1.MPI_TAG == 5);
448         check(s1.MPI_ERROR == MPI_ERR_DIMS);
449         check(msg != MPI_MESSAGE_NULL);
450
451         count = -1;
452         MPI_Get_count(&s1, vectype, &count);
453         check(count == 1);
454
455         memset(recvbuf, 0, 8 * sizeof(int));
456         MPI_Mrecv(recvbuf, 1, vectype, &msg, &s2);
457         check(recvbuf[0] == 0xdeadbeef);
458         for (i = 1; i < 4; i++)
459             check(recvbuf[i] == 0);
460         check(recvbuf[4] = 0xfeedface);
461         for (i = 5; i < 8; i++)
462             check(recvbuf[i] == 0);
463         check(s2.MPI_SOURCE == 0);
464         check(s2.MPI_TAG == 5);
465         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
466         check(msg == MPI_MESSAGE_NULL);
467     }
468     MPI_Type_free(&vectype);
469
470     /* test 11: mprobe+mrecv noncontiguous datatype LARGE */
471     MPI_Type_vector(LARGE_DIM, LARGE_DIM - 1, LARGE_DIM, MPI_INT, &vectype);
472     MPI_Type_commit(&vectype);
473     if (rank == 0) {
474         for (i = 0; i < LARGE_SZ; i++)
475             sendbuf[i] = i;
476         MPI_Send(sendbuf, 1, vectype, 1, 5, MPI_COMM_WORLD);
477     }
478     else {
479         int idx = 0;
480
481         memset(&s1, 0xab, sizeof(MPI_Status));
482         memset(&s2, 0xab, sizeof(MPI_Status));
483         /* the error field should remain unmodified */
484         s1.MPI_ERROR = MPI_ERR_DIMS;
485         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
486
487         msg = MPI_MESSAGE_NULL;
488         MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
489         check(s1.MPI_SOURCE == 0);
490         check(s1.MPI_TAG == 5);
491         check(s1.MPI_ERROR == MPI_ERR_DIMS);
492         check(msg != MPI_MESSAGE_NULL);
493
494         count = -1;
495         MPI_Get_count(&s1, vectype, &count);
496         check(count == 1);
497
498         memset(recvbuf, 0, LARGE_SZ * sizeof(int));
499         MPI_Mrecv(recvbuf, 1, vectype, &msg, &s2);
500         for (i = 0; i < LARGE_DIM; i++) {
501             int j;
502             for (j = 0; j < LARGE_DIM - 1; j++) {
503                 check(recvbuf[idx] == idx);
504                 ++idx;
505             }
506             check(recvbuf[idx++] == 0);
507         }
508         check(s2.MPI_SOURCE == 0);
509         check(s2.MPI_TAG == 5);
510         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
511         check(msg == MPI_MESSAGE_NULL);
512     }
513     MPI_Type_free(&vectype);
514
515     /* test 12: order test */
516     if (rank == 0) {
517         MPI_Request lrequest[2];
518         sendbuf[0] = 0xdeadbeef;
519         sendbuf[1] = 0xfeedface;
520         sendbuf[2] = 0xdeadbeef;
521         sendbuf[3] = 0xfeedface;
522         sendbuf[4] = 0xdeadbeef;
523         sendbuf[5] = 0xfeedface;
524         MPI_Isend(&sendbuf[0], 4, MPI_INT, 1, 6, MPI_COMM_WORLD, &lrequest[0]);
525         MPI_Isend(&sendbuf[4], 2, MPI_INT, 1, 6, MPI_COMM_WORLD, &lrequest[1]);
526         MPI_Waitall(2, &lrequest[0], MPI_STATUSES_IGNORE);
527     }
528     else {
529         memset(&s1, 0xab, sizeof(MPI_Status));
530         memset(&s2, 0xab, sizeof(MPI_Status));
531         /* the error field should remain unmodified */
532         s1.MPI_ERROR = MPI_ERR_DIMS;
533         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
534
535         msg = MPI_MESSAGE_NULL;
536         MPI_Mprobe(0, 6, MPI_COMM_WORLD, &msg, &s1);
537         check(s1.MPI_SOURCE == 0);
538         check(s1.MPI_TAG == 6);
539         check(s1.MPI_ERROR == MPI_ERR_DIMS);
540         check(msg != MPI_MESSAGE_NULL);
541
542         count = -1;
543         MPI_Get_count(&s1, MPI_INT, &count);
544         check(count == 4);
545
546         recvbuf[0] = 0x01234567;
547         recvbuf[1] = 0x89abcdef;
548         MPI_Recv(recvbuf, 2, MPI_INT, 0, 6, MPI_COMM_WORLD, &s2);
549         check(s2.MPI_SOURCE == 0);
550         check(s2.MPI_TAG == 6);
551         check(recvbuf[0] == 0xdeadbeef);
552         check(recvbuf[1] == 0xfeedface);
553
554         recvbuf[0] = 0x01234567;
555         recvbuf[1] = 0x89abcdef;
556         recvbuf[2] = 0x01234567;
557         recvbuf[3] = 0x89abcdef;
558         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
559
560         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
561         check(recvbuf[0] == 0xdeadbeef);
562         check(recvbuf[1] == 0xfeedface);
563         check(recvbuf[2] == 0xdeadbeef);
564         check(recvbuf[3] == 0xfeedface);
565         check(s2.MPI_SOURCE == 0);
566         check(s2.MPI_TAG == 6);
567         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
568         check(msg == MPI_MESSAGE_NULL);
569     }
570
571     free(sendbuf);
572     free(recvbuf);
573
574     /* TODO MPI_ANY_SOURCE and MPI_ANY_TAG should be tested as well */
575     /* TODO a full range of message sizes should be tested too */
576     /* TODO threaded tests are also needed, but they should go in a separate
577      * program */
578
579     /* simple test to ensure that c2f/f2c routines are present (initially missed
580      * in MPICH impl) */
581     {
582         MPI_Fint f_handle = 0xdeadbeef;
583         f_handle = MPI_Message_c2f(MPI_MESSAGE_NULL);
584         msg = MPI_Message_f2c(f_handle);
585         check(f_handle != 0xdeadbeef);
586         check(msg == MPI_MESSAGE_NULL);
587
588         /* PMPI_ versions should also exists */
589         f_handle = 0xdeadbeef;
590         f_handle = PMPI_Message_c2f(MPI_MESSAGE_NULL);
591         msg = PMPI_Message_f2c(f_handle);
592         check(f_handle != 0xdeadbeef);
593         check(msg == MPI_MESSAGE_NULL);
594     }
595
596   epilogue:
597     MPI_Reduce((rank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
598     if (rank == 0) {
599         if (errs) {
600             printf("found %d errors\n", errs);
601         }
602         else {
603             printf(" No errors\n");
604         }
605     }
606
607     MPI_Finalize();
608
609     return 0;
610 }