1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
3 * (C) 2012 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
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
20 /* assert-like macro that bumps the err count and emits a message */
26 fprintf(stderr, "check failed: (%s), line %d\n", #x_, __LINE__); \
31 int main(int argc, char **argv)
35 #ifdef TEST_MPROBE_ROUTINES
37 int sendbuf[8], recvbuf[8];
44 MPI_Init(&argc, &argv);
46 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
47 MPI_Comm_size(MPI_COMM_WORLD, &size);
50 printf("this test requires at least 2 processes\n");
51 MPI_Abort(MPI_COMM_WORLD, 1);
55 /* all processes besides ranks 0 & 1 aren't used by this test */
60 #ifdef TEST_MPROBE_ROUTINES
61 /* test 0: simple send & mprobe+mrecv */
63 sendbuf[0] = 0xdeadbeef;
64 sendbuf[1] = 0xfeedface;
65 MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
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;
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);
82 MPI_Get_count(&s1, MPI_INT, &count);
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);
96 /* test 1: simple send & mprobe+imrecv */
98 sendbuf[0] = 0xdeadbeef;
99 sendbuf[1] = 0xfeedface;
100 MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
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;
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);
117 MPI_Get_count(&s1, MPI_INT, &count);
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);
134 /* test 2: simple send & improbe+mrecv */
136 sendbuf[0] = 0xdeadbeef;
137 sendbuf[1] = 0xfeedface;
138 MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
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;
147 msg = MPI_MESSAGE_NULL;
149 check(msg == MPI_MESSAGE_NULL);
150 MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
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);
158 MPI_Get_count(&s1, MPI_INT, &count);
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);
172 /* test 3: simple send & improbe+imrecv */
174 sendbuf[0] = 0xdeadbeef;
175 sendbuf[1] = 0xfeedface;
176 MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
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;
185 msg = MPI_MESSAGE_NULL;
187 check(msg == MPI_MESSAGE_NULL);
188 MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
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);
196 MPI_Get_count(&s1, MPI_INT, &count);
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);
211 /* test 4: mprobe+mrecv with MPI_PROC_NULL */
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;
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);
227 MPI_Get_count(&s1, MPI_INT, &count);
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);
242 MPI_Get_count(&s2, MPI_INT, &count);
246 /* test 5: mprobe+imrecv with MPI_PROC_NULL */
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;
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);
261 MPI_Get_count(&s1, MPI_INT, &count);
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);
270 MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */
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);
281 MPI_Get_count(&s2, MPI_INT, &count);
285 /* test 6: improbe+mrecv with MPI_PROC_NULL */
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;
293 msg = MPI_MESSAGE_NULL;
295 MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
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);
302 MPI_Get_count(&s1, MPI_INT, &count);
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);
317 MPI_Get_count(&s2, MPI_INT, &count);
321 /* test 7: improbe+imrecv */
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;
329 msg = MPI_MESSAGE_NULL;
330 MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
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);
337 MPI_Get_count(&s1, MPI_INT, &count);
340 rreq = MPI_REQUEST_NULL;
341 MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
342 check(rreq != MPI_REQUEST_NULL);
344 MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */
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);
355 MPI_Get_count(&s2, MPI_INT, &count);
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
364 /* simple test to ensure that c2f/f2c routines are present (initially missed
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);
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);
381 #endif /* TEST_MPROBE_ROUTINES */
384 MPI_Reduce((rank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
387 printf("found %d errors\n", errs);
390 printf(" No errors\n");