Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Make smpi_process_init public, and avoid errors with smpiff.
[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 found, completed;
35     int rank, size;
36     int sendbuf[8], recvbuf[8];
37     int count;
38 #ifdef TEST_MPROBE_ROUTINES
39     MPI_Message msg;
40 #endif
41     MPI_Request rreq;
42     MPI_Status s1, s2;
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     }
53
54     /* all processes besides ranks 0 & 1 aren't used by this test */
55     if (rank >= 2) {
56         goto epilogue;
57     }
58
59 #ifdef TEST_MPROBE_ROUTINES
60     /* test 0: simple send & mprobe+mrecv */
61     if (rank == 0) {
62         sendbuf[0] = 0xdeadbeef;
63         sendbuf[1] = 0xfeedface;
64         MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
65     }
66     else {
67         memset(&s1, 0xab, sizeof(MPI_Status));
68         memset(&s2, 0xab, sizeof(MPI_Status));
69         /* the error field should remain unmodified */
70         s1.MPI_ERROR = MPI_ERR_DIMS;
71         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
72
73         msg = MPI_MESSAGE_NULL;
74         MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
75         check(s1.MPI_SOURCE == 0);
76         check(s1.MPI_TAG == 5);
77         check(s1.MPI_ERROR == MPI_ERR_DIMS);
78         check(msg != MPI_MESSAGE_NULL);
79
80         count = -1;
81         MPI_Get_count(&s1, MPI_INT, &count);
82         check(count == 2);
83
84         recvbuf[0] = 0x01234567;
85         recvbuf[1] = 0x89abcdef;
86         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
87         check(recvbuf[0] == 0xdeadbeef);
88         check(recvbuf[1] == 0xfeedface);
89         check(s2.MPI_SOURCE == 0);
90         check(s2.MPI_TAG == 5);
91         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
92         check(msg == MPI_MESSAGE_NULL);
93     }
94
95     /* test 1: simple send & mprobe+imrecv */
96     if (rank == 0) {
97         sendbuf[0] = 0xdeadbeef;
98         sendbuf[1] = 0xfeedface;
99         MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
100     }
101     else {
102         memset(&s1, 0xab, sizeof(MPI_Status));
103         memset(&s2, 0xab, sizeof(MPI_Status));
104         /* the error field should remain unmodified */
105         s1.MPI_ERROR = MPI_ERR_DIMS;
106         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
107
108         msg = MPI_MESSAGE_NULL;
109         MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
110         check(s1.MPI_SOURCE == 0);
111         check(s1.MPI_TAG == 5);
112         check(s1.MPI_ERROR == MPI_ERR_DIMS);
113         check(msg != MPI_MESSAGE_NULL);
114
115         count = -1;
116         MPI_Get_count(&s1, MPI_INT, &count);
117         check(count == 2);
118
119         rreq = MPI_REQUEST_NULL;
120         recvbuf[0] = 0x01234567;
121         recvbuf[1] = 0x89abcdef;
122         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
123         check(rreq != MPI_REQUEST_NULL);
124         MPI_Wait(&rreq, &s2);
125         check(recvbuf[0] == 0xdeadbeef);
126         check(recvbuf[1] == 0xfeedface);
127         check(s2.MPI_SOURCE == 0);
128         check(s2.MPI_TAG == 5);
129         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
130         check(msg == MPI_MESSAGE_NULL);
131     }
132
133     /* test 2: simple send & improbe+mrecv */
134     if (rank == 0) {
135         sendbuf[0] = 0xdeadbeef;
136         sendbuf[1] = 0xfeedface;
137         MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
138     }
139     else {
140         memset(&s1, 0xab, sizeof(MPI_Status));
141         memset(&s2, 0xab, sizeof(MPI_Status));
142         /* the error field should remain unmodified */
143         s1.MPI_ERROR = MPI_ERR_DIMS;
144         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
145
146         msg = MPI_MESSAGE_NULL;
147         do {
148             check(msg == MPI_MESSAGE_NULL);
149             MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
150         } while (!found);
151         check(msg != MPI_MESSAGE_NULL);
152         check(s1.MPI_SOURCE == 0);
153         check(s1.MPI_TAG == 5);
154         check(s1.MPI_ERROR == MPI_ERR_DIMS);
155
156         count = -1;
157         MPI_Get_count(&s1, MPI_INT, &count);
158         check(count == 2);
159
160         recvbuf[0] = 0x01234567;
161         recvbuf[1] = 0x89abcdef;
162         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
163         check(recvbuf[0] == 0xdeadbeef);
164         check(recvbuf[1] == 0xfeedface);
165         check(s2.MPI_SOURCE == 0);
166         check(s2.MPI_TAG == 5);
167         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
168         check(msg == MPI_MESSAGE_NULL);
169     }
170
171     /* test 3: simple send & improbe+imrecv */
172     if (rank == 0) {
173         sendbuf[0] = 0xdeadbeef;
174         sendbuf[1] = 0xfeedface;
175         MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
176     }
177     else {
178         memset(&s1, 0xab, sizeof(MPI_Status));
179         memset(&s2, 0xab, sizeof(MPI_Status));
180         /* the error field should remain unmodified */
181         s1.MPI_ERROR = MPI_ERR_DIMS;
182         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
183
184         msg = MPI_MESSAGE_NULL;
185         do {
186             check(msg == MPI_MESSAGE_NULL);
187             MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
188         } while (!found);
189         check(msg != MPI_MESSAGE_NULL);
190         check(s1.MPI_SOURCE == 0);
191         check(s1.MPI_TAG == 5);
192         check(s1.MPI_ERROR == MPI_ERR_DIMS);
193
194         count = -1;
195         MPI_Get_count(&s1, MPI_INT, &count);
196         check(count == 2);
197
198         rreq = MPI_REQUEST_NULL;
199         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
200         check(rreq != MPI_REQUEST_NULL);
201         MPI_Wait(&rreq, &s2);
202         check(recvbuf[0] == 0xdeadbeef);
203         check(recvbuf[1] == 0xfeedface);
204         check(s2.MPI_SOURCE == 0);
205         check(s2.MPI_TAG == 5);
206         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
207         check(msg == MPI_MESSAGE_NULL);
208     }
209
210     /* test 4: mprobe+mrecv with MPI_PROC_NULL */
211     {
212         memset(&s1, 0xab, sizeof(MPI_Status));
213         memset(&s2, 0xab, sizeof(MPI_Status));
214         /* the error field should remain unmodified */
215         s1.MPI_ERROR = MPI_ERR_DIMS;
216         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
217
218         msg = MPI_MESSAGE_NULL;
219         MPI_Mprobe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &msg, &s1);
220         check(s1.MPI_SOURCE == MPI_PROC_NULL);
221         check(s1.MPI_TAG == MPI_ANY_TAG);
222         check(s1.MPI_ERROR == MPI_ERR_DIMS);
223         check(msg == MPI_MESSAGE_NO_PROC);
224
225         count = -1;
226         MPI_Get_count(&s1, MPI_INT, &count);
227         check(count == 0);
228
229         recvbuf[0] = 0x01234567;
230         recvbuf[1] = 0x89abcdef;
231         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
232         /* recvbuf should remain unmodified */
233         check(recvbuf[0] == 0x01234567);
234         check(recvbuf[1] == 0x89abcdef);
235         /* should get back "proc null status" */
236         check(s2.MPI_SOURCE == MPI_PROC_NULL);
237         check(s2.MPI_TAG == MPI_ANY_TAG);
238         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
239         check(msg == MPI_MESSAGE_NULL);
240         count = -1;
241         MPI_Get_count(&s2, MPI_INT, &count);
242         check(count == 0);
243     }
244
245     /* test 5: mprobe+imrecv with MPI_PROC_NULL */
246     {
247         memset(&s1, 0xab, sizeof(MPI_Status));
248         memset(&s2, 0xab, sizeof(MPI_Status));
249         /* the error field should remain unmodified */
250         s1.MPI_ERROR = MPI_ERR_DIMS;
251         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
252
253         msg = MPI_MESSAGE_NULL;
254         MPI_Mprobe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &msg, &s1);
255         check(s1.MPI_SOURCE == MPI_PROC_NULL);
256         check(s1.MPI_TAG == MPI_ANY_TAG);
257         check(s1.MPI_ERROR == MPI_ERR_DIMS);
258         check(msg == MPI_MESSAGE_NO_PROC);
259         count = -1;
260         MPI_Get_count(&s1, MPI_INT, &count);
261         check(count == 0);
262
263         rreq = MPI_REQUEST_NULL;
264         recvbuf[0] = 0x01234567;
265         recvbuf[1] = 0x89abcdef;
266         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
267         check(rreq != MPI_REQUEST_NULL);
268         completed = 0;
269         MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */
270         check(completed);
271         /* recvbuf should remain unmodified */
272         check(recvbuf[0] == 0x01234567);
273         check(recvbuf[1] == 0x89abcdef);
274         /* should get back "proc null status" */
275         check(s2.MPI_SOURCE == MPI_PROC_NULL);
276         check(s2.MPI_TAG == MPI_ANY_TAG);
277         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
278         check(msg == MPI_MESSAGE_NULL);
279         count = -1;
280         MPI_Get_count(&s2, MPI_INT, &count);
281         check(count == 0);
282     }
283
284     /* test 6: improbe+mrecv with MPI_PROC_NULL */
285     {
286         memset(&s1, 0xab, sizeof(MPI_Status));
287         memset(&s2, 0xab, sizeof(MPI_Status));
288         /* the error field should remain unmodified */
289         s1.MPI_ERROR = MPI_ERR_DIMS;
290         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
291
292         msg = MPI_MESSAGE_NULL;
293         found = 0;
294         MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
295         check(found);
296         check(msg == MPI_MESSAGE_NO_PROC);
297         check(s1.MPI_SOURCE == MPI_PROC_NULL);
298         check(s1.MPI_TAG == MPI_ANY_TAG);
299         check(s1.MPI_ERROR == MPI_ERR_DIMS);
300         count = -1;
301         MPI_Get_count(&s1, MPI_INT, &count);
302         check(count == 0);
303
304         recvbuf[0] = 0x01234567;
305         recvbuf[1] = 0x89abcdef;
306         MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
307         /* recvbuf should remain unmodified */
308         check(recvbuf[0] == 0x01234567);
309         check(recvbuf[1] == 0x89abcdef);
310         /* should get back "proc null status" */
311         check(s2.MPI_SOURCE == MPI_PROC_NULL);
312         check(s2.MPI_TAG == MPI_ANY_TAG);
313         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
314         check(msg == MPI_MESSAGE_NULL);
315         count = -1;
316         MPI_Get_count(&s2, MPI_INT, &count);
317         check(count == 0);
318     }
319
320     /* test 7: improbe+imrecv */
321     {
322         memset(&s1, 0xab, sizeof(MPI_Status));
323         memset(&s2, 0xab, sizeof(MPI_Status));
324         /* the error field should remain unmodified */
325         s1.MPI_ERROR = MPI_ERR_DIMS;
326         s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
327
328         msg = MPI_MESSAGE_NULL;
329         MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
330         check(found);
331         check(msg == MPI_MESSAGE_NO_PROC);
332         check(s1.MPI_SOURCE == MPI_PROC_NULL);
333         check(s1.MPI_TAG == MPI_ANY_TAG);
334         check(s1.MPI_ERROR == MPI_ERR_DIMS);
335         count = -1;
336         MPI_Get_count(&s1, MPI_INT, &count);
337         check(count == 0);
338
339         rreq = MPI_REQUEST_NULL;
340         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
341         check(rreq != MPI_REQUEST_NULL);
342         completed = 0;
343         MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */
344         check(completed);
345         /* recvbuf should remain unmodified */
346         check(recvbuf[0] == 0x01234567);
347         check(recvbuf[1] == 0x89abcdef);
348         /* should get back "proc null status" */
349         check(s2.MPI_SOURCE == MPI_PROC_NULL);
350         check(s2.MPI_TAG == MPI_ANY_TAG);
351         check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
352         check(msg == MPI_MESSAGE_NULL);
353         count = -1;
354         MPI_Get_count(&s2, MPI_INT, &count);
355         check(count == 0);
356     }
357
358     /* TODO MPI_ANY_SOURCE and MPI_ANY_TAG should be tested as well */
359     /* TODO a full range of message sizes should be tested too */
360     /* TODO threaded tests are also needed, but they should go in a separate
361      * program */
362
363     /* simple test to ensure that c2f/f2c routines are present (initially missed
364      * in MPICH impl) */
365     {
366         MPI_Fint f_handle = 0xdeadbeef;
367         f_handle = MPI_Message_c2f(MPI_MESSAGE_NULL);
368         msg = MPI_Message_f2c(f_handle);
369         check(f_handle != 0xdeadbeef);
370         check(msg == MPI_MESSAGE_NULL);
371
372         /* PMPI_ versions should also exists */
373         f_handle = 0xdeadbeef;
374         f_handle = PMPI_Message_c2f(MPI_MESSAGE_NULL);
375         msg = PMPI_Message_f2c(f_handle);
376         check(f_handle != 0xdeadbeef);
377         check(msg == MPI_MESSAGE_NULL);
378     }
379
380 #endif /* TEST_MPROBE_ROUTINES */
381
382 epilogue:
383     MPI_Reduce((rank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
384     if (rank == 0) {
385         if (errs) {
386             printf("found %d errors\n", errs);
387         }
388         else {
389             printf(" No errors\n");
390         }
391     }
392
393     MPI_Finalize();
394
395     return 0;
396 }
397