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)
36 int sendbuf[8], recvbuf[8];
38 #ifdef TEST_MPROBE_ROUTINES
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);
54 /* all processes besides ranks 0 & 1 aren't used by this test */
59 #ifdef TEST_MPROBE_ROUTINES
60 /* test 0: simple send & mprobe+mrecv */
62 sendbuf[0] = 0xdeadbeef;
63 sendbuf[1] = 0xfeedface;
64 MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
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;
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);
81 MPI_Get_count(&s1, MPI_INT, &count);
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);
95 /* test 1: simple send & mprobe+imrecv */
97 sendbuf[0] = 0xdeadbeef;
98 sendbuf[1] = 0xfeedface;
99 MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
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;
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);
116 MPI_Get_count(&s1, MPI_INT, &count);
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);
133 /* test 2: simple send & improbe+mrecv */
135 sendbuf[0] = 0xdeadbeef;
136 sendbuf[1] = 0xfeedface;
137 MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
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;
146 msg = MPI_MESSAGE_NULL;
148 check(msg == MPI_MESSAGE_NULL);
149 MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
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);
157 MPI_Get_count(&s1, MPI_INT, &count);
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);
171 /* test 3: simple send & improbe+imrecv */
173 sendbuf[0] = 0xdeadbeef;
174 sendbuf[1] = 0xfeedface;
175 MPI_Send(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
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;
184 msg = MPI_MESSAGE_NULL;
186 check(msg == MPI_MESSAGE_NULL);
187 MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1);
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);
195 MPI_Get_count(&s1, MPI_INT, &count);
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);
210 /* test 4: mprobe+mrecv with MPI_PROC_NULL */
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;
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);
226 MPI_Get_count(&s1, MPI_INT, &count);
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);
241 MPI_Get_count(&s2, MPI_INT, &count);
245 /* test 5: mprobe+imrecv with MPI_PROC_NULL */
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;
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);
260 MPI_Get_count(&s1, MPI_INT, &count);
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);
269 MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */
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);
280 MPI_Get_count(&s2, MPI_INT, &count);
284 /* test 6: improbe+mrecv with MPI_PROC_NULL */
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;
292 msg = MPI_MESSAGE_NULL;
294 MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
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);
301 MPI_Get_count(&s1, MPI_INT, &count);
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);
316 MPI_Get_count(&s2, MPI_INT, &count);
320 /* test 7: improbe+imrecv */
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;
328 msg = MPI_MESSAGE_NULL;
329 MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1);
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);
336 MPI_Get_count(&s1, MPI_INT, &count);
339 rreq = MPI_REQUEST_NULL;
340 MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
341 check(rreq != MPI_REQUEST_NULL);
343 MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */
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);
354 MPI_Get_count(&s2, MPI_INT, &count);
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
363 /* simple test to ensure that c2f/f2c routines are present (initially missed
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);
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);
380 #endif /* TEST_MPROBE_ROUTINES */
383 MPI_Reduce((rank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
386 printf("found %d errors\n", errs);
389 printf(" No errors\n");