Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Change include order for smpi tests/examples to avoid conflicts
[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 /* This is a temporary #ifdef to control whether we test this functionality.  A
14  * configure-test or similar would be better.  Eventually the MPI-3 standard
15  * will be released and this can be gated on a MPI_VERSION check */
16 #if !defined(USE_STRICT_MPI) && defined(MPICH)
17 #define TEST_MPROBE_ROUTINES 1
18 #endif
19
20 /* assert-like macro that bumps the err count and emits a message */
21 #define check(x_)                                                                 \
22     do {                                                                          \
23         if (!(x_)) {                                                              \
24             ++errs;                                                               \
25             if (errs < 10) {                                                      \
26                 fprintf(stderr, "check failed: (%s), line %d\n", #x_, __LINE__); \
27             }                                                                     \
28         }                                                                         \
29     } while (0)
30
31 int main(int argc, char **argv)
32 {
33     int errs = 0;
34     int rank, size;
35 #ifdef TEST_MPROBE_ROUTINES
36     int found, completed;
37     int sendbuf[8], recvbuf[8];
38     int count;
39     MPI_Message msg;
40     MPI_Request rreq;
41     MPI_Status s1, s2;
42 #endif
43
44     MPI_Init(&argc, &argv);
45
46     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
47     MPI_Comm_size(MPI_COMM_WORLD, &size);
48
49     if (size < 2) {
50         printf("this test requires at least 2 processes\n");
51         MPI_Abort(MPI_COMM_WORLD, 1);
52         exit(1);
53     }
54
55     /* all processes besides ranks 0 & 1 aren't used by this test */
56     if (rank >= 2) {
57         goto epilogue;
58     }
59
60 #ifdef TEST_MPROBE_ROUTINES
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     /* TODO MPI_ANY_SOURCE and MPI_ANY_TAG should be tested as well */
360     /* TODO a full range of message sizes should be tested too */
361     /* TODO threaded tests are also needed, but they should go in a separate
362      * program */
363
364     /* simple test to ensure that c2f/f2c routines are present (initially missed
365      * in MPICH impl) */
366     {
367         MPI_Fint f_handle = 0xdeadbeef;
368         f_handle = MPI_Message_c2f(MPI_MESSAGE_NULL);
369         msg = MPI_Message_f2c(f_handle);
370         check(f_handle != 0xdeadbeef);
371         check(msg == MPI_MESSAGE_NULL);
372
373         /* PMPI_ versions should also exists */
374         f_handle = 0xdeadbeef;
375         f_handle = PMPI_Message_c2f(MPI_MESSAGE_NULL);
376         msg = PMPI_Message_f2c(f_handle);
377         check(f_handle != 0xdeadbeef);
378         check(msg == MPI_MESSAGE_NULL);
379     }
380
381 #endif /* TEST_MPROBE_ROUTINES */
382
383 epilogue:
384     MPI_Reduce((rank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
385     if (rank == 0) {
386         if (errs) {
387             printf("found %d errors\n", errs);
388         }
389         else {
390             printf(" No errors\n");
391         }
392     }
393
394     MPI_Finalize();
395
396     return 0;
397 }
398