2 c This program was inspired by a bug report from
3 c fsset@corelli.lerc.nasa.gov (Scott Townsend)
4 c The original version of this program was submitted by email to
5 c mpi-bugs and is in the directory mpich/bugs/ssend (not distributed
6 c with the distribution). This program was modified by William
7 c Gropp (to correct a few errors and make more consistent with the
8 c structure of the test programs in the examples/test/pt2pt directory.
10 c A C version of this program is in allpairc.c
20 call MPI_Finalize(ierr)
24 c------------------------------------------------------------------------------
26 c Simple pair communication exercises.
28 c------------------------------------------------------------------------------
32 parameter (TEST_SIZE=2000)
34 integer ierr, prev, next, count, tag, index, i, outcount,
35 . requests(2), indices(2), rank, size,
36 . status(MPI_STATUS_SIZE), statuses(MPI_STATUS_SIZE,2)
39 real send_buf( TEST_SIZE ), recv_buf ( TEST_SIZE )
41 call MPI_Comm_rank( MPI_COMM_WORLD, rank, ierr )
42 call MPI_Comm_size( MPI_COMM_WORLD, size, ierr )
44 print *, 'Allpair test requires exactly 2 processes'
45 call MPI_Abort( MPI_COMM_WORLD, 1, ierr )
47 C print *, ' about to do dup'
48 call MPI_Comm_dup( MPI_COMM_WORLD, dupcom, ierr )
51 if (next .ge. size) next = 0
54 if (prev .lt. 0) prev = size - 1
65 call clear_test_data(recv_buf,TEST_SIZE)
69 call init_test_data(send_buf,TEST_SIZE)
71 call MPI_Send(send_buf, count, MPI_REAL, next, tag,
72 . MPI_COMM_WORLD, ierr)
74 call MPI_Recv(recv_buf, TEST_SIZE, MPI_REAL,
75 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
78 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
81 call MPI_Recv(recv_buf, TEST_SIZE, MPI_REAL,
82 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
85 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
88 call MPI_Send(recv_buf, count, MPI_REAL, next, tag,
89 . MPI_COMM_WORLD, ierr)
92 c Ready sends. Note that we must insure that the receive is posted
93 c before the rsend; this requires using Irecv.
100 count = TEST_SIZE / 3
102 call clear_test_data(recv_buf,TEST_SIZE)
104 if (rank .eq. 0) then
106 call init_test_data(send_buf,TEST_SIZE)
108 call MPI_Recv( MPI_BOTTOM, 0, MPI_INTEGER, next, tag,
109 . MPI_COMM_WORLD, status, ierr )
111 call MPI_Rsend(send_buf, count, MPI_REAL, next, tag,
112 . MPI_COMM_WORLD, ierr)
114 call MPI_Probe(MPI_ANY_SOURCE, tag,
115 . MPI_COMM_WORLD, status, ierr)
117 if (status(MPI_SOURCE) .ne. prev) then
118 print *, 'Incorrect source, expected', prev,
119 . ', got', status(MPI_SOURCE)
122 if (status(MPI_TAG) .ne. tag) then
123 print *, 'Incorrect tag, expected', tag,
124 . ', got', status(MPI_TAG)
127 call MPI_Get_count(status, MPI_REAL, i, ierr)
129 if (i .ne. count) then
130 print *, 'Incorrect count, expected', count,
134 call MPI_Recv(recv_buf, TEST_SIZE, MPI_REAL,
135 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
138 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
143 call MPI_Irecv(recv_buf, TEST_SIZE, MPI_REAL,
144 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
146 call MPI_Send( MPI_BOTTOM, 0, MPI_INTEGER, next, tag,
147 . MPI_COMM_WORLD, ierr )
148 call MPI_Wait( requests(1), status, ierr )
149 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
152 call MPI_Send(recv_buf, count, MPI_REAL, next, tag,
153 . MPI_COMM_WORLD, ierr)
158 if (rank .eq. 0) then
163 count = TEST_SIZE / 3
165 call clear_test_data(recv_buf,TEST_SIZE)
167 if (rank .eq. 0) then
169 call init_test_data(send_buf,TEST_SIZE)
171 call MPI_Iprobe(MPI_ANY_SOURCE, tag,
172 . MPI_COMM_WORLD, flag, status, ierr)
175 print *, 'Iprobe succeeded! source', status(MPI_SOURCE),
176 . ', tag', status(MPI_TAG)
179 call MPI_Ssend(send_buf, count, MPI_REAL, next, tag,
180 . MPI_COMM_WORLD, ierr)
182 do while (.not. flag)
183 call MPI_Iprobe(MPI_ANY_SOURCE, tag,
184 . MPI_COMM_WORLD, flag, status, ierr)
187 if (status(MPI_SOURCE) .ne. prev) then
188 print *, 'Incorrect source, expected', prev,
189 . ', got', status(MPI_SOURCE)
192 if (status(MPI_TAG) .ne. tag) then
193 print *, 'Incorrect tag, expected', tag,
194 . ', got', status(MPI_TAG)
197 call MPI_Get_count(status, MPI_REAL, i, ierr)
199 if (i .ne. count) then
200 print *, 'Incorrect count, expected', count,
204 call MPI_Recv(recv_buf, TEST_SIZE, MPI_REAL,
205 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
208 call msg_check( recv_buf, prev, tag, count, status,
209 $ TEST_SIZE, 'ssend and recv' )
213 call MPI_Recv(recv_buf, TEST_SIZE, MPI_REAL,
214 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
217 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
220 call MPI_Ssend(recv_buf, count, MPI_REAL, next, tag,
221 . MPI_COMM_WORLD, ierr)
224 c Nonblocking normal sends
226 if (rank .eq. 0) then
231 count = TEST_SIZE / 5
233 call clear_test_data(recv_buf,TEST_SIZE)
235 if (rank .eq. 0) then
237 call MPI_Irecv(recv_buf, TEST_SIZE, MPI_REAL,
238 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
241 call init_test_data(send_buf,TEST_SIZE)
243 call MPI_Isend(send_buf, count, MPI_REAL, next, tag,
244 . MPI_COMM_WORLD, requests(2), ierr)
246 call MPI_Waitall(2, requests, statuses, ierr)
248 call rq_check( requests, 2, 'isend and irecv' )
250 call msg_check( recv_buf, prev, tag, count, statuses(1,1),
251 $ TEST_SIZE, 'isend and irecv' )
255 call MPI_Recv(recv_buf, TEST_SIZE, MPI_REAL,
256 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
259 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
260 . 'isend and irecv' )
262 call MPI_Isend(recv_buf, count, MPI_REAL, next, tag,
263 . MPI_COMM_WORLD, requests(1), ierr)
265 call MPI_Wait(requests(1), status, ierr)
267 call rq_check( requests(1), 1, 'isend and irecv' )
271 c Nonblocking ready sends
273 if (rank .eq. 0) then
278 count = TEST_SIZE / 3
280 call clear_test_data(recv_buf,TEST_SIZE)
283 c This test needs work for comm_size > 2
285 if (rank .eq. 0) then
287 call MPI_Irecv(recv_buf, TEST_SIZE, MPI_REAL,
288 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
291 call init_test_data(send_buf,TEST_SIZE)
293 call MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INTEGER, next, 0,
294 . MPI_BOTTOM, 0, MPI_INTEGER, next, 0,
295 . dupcom, status, ierr )
297 call MPI_Irsend(send_buf, count, MPI_REAL, next, tag,
298 . MPI_COMM_WORLD, requests(2), ierr)
301 do while (index .ne. 1)
302 call MPI_Waitany(2, requests, index, statuses, ierr)
305 call rq_check( requests(1), 1, 'irsend and irecv' )
307 call msg_check( recv_buf, prev, tag, count, statuses,
308 $ TEST_SIZE, 'irsend and irecv' )
312 call MPI_Irecv(recv_buf, TEST_SIZE, MPI_REAL,
313 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
316 call MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INTEGER, next, 0,
317 . MPI_BOTTOM, 0, MPI_INTEGER, next, 0,
318 . dupcom, status, ierr )
321 do while (.not. flag)
322 call MPI_Test(requests(1), flag, status, ierr)
325 call rq_check( requests, 1, 'irsend and irecv (test)' )
327 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
328 . 'irsend and irecv' )
330 call MPI_Irsend(recv_buf, count, MPI_REAL, next, tag,
331 . MPI_COMM_WORLD, requests(1), ierr)
333 call MPI_Waitall(1, requests, statuses, ierr)
335 call rq_check( requests, 1, 'irsend and irecv' )
340 c Nonblocking synchronous sends
342 if (rank .eq. 0) then
347 count = TEST_SIZE / 3
349 call clear_test_data(recv_buf,TEST_SIZE)
351 if (rank .eq. 0) then
353 call MPI_Irecv(recv_buf, TEST_SIZE, MPI_REAL,
354 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
357 call init_test_data(send_buf,TEST_SIZE)
359 call MPI_Issend(send_buf, count, MPI_REAL, next, tag,
360 . MPI_COMM_WORLD, requests(2), ierr)
363 do while (.not. flag)
364 call MPI_Testall(2, requests, flag, statuses, ierr)
365 C print *, 'flag = ', flag
368 call rq_check( requests, 2, 'issend and irecv (testall)' )
370 call msg_check( recv_buf, prev, tag, count, statuses(1,1),
371 $ TEST_SIZE, 'issend and recv (testall)' )
375 call MPI_Recv(recv_buf, TEST_SIZE, MPI_REAL,
376 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
379 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
380 . 'issend and recv' )
382 call MPI_Issend(recv_buf, count, MPI_REAL, next, tag,
383 . MPI_COMM_WORLD, requests(1), ierr)
386 do while (.not. flag)
387 call MPI_Testany(1, requests(1), index, flag,
388 . statuses(1,1), ierr)
389 c print *, 'flag = ', flag
392 call rq_check( requests, 1, 'issend and recv (testany)' )
396 c Persistent normal sends
398 if (rank .eq. 0) then
399 print *, ' Send_init'
403 count = TEST_SIZE / 5
405 call clear_test_data(recv_buf,TEST_SIZE)
407 call MPI_Send_init(send_buf, count, MPI_REAL, next, tag,
408 . MPI_COMM_WORLD, requests(1), ierr)
410 call MPI_Recv_init(recv_buf, TEST_SIZE, MPI_REAL,
411 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
414 if (rank .eq. 0) then
416 call init_test_data(send_buf,TEST_SIZE)
418 call MPI_Startall(2, requests, ierr)
419 call MPI_Waitall(2, requests, statuses, ierr)
421 call msg_check( recv_buf, prev, tag, count, statuses(1,2),
422 $ TEST_SIZE, 'persistent send/recv' )
426 call MPI_Start(requests(2), ierr)
427 call MPI_Wait(requests(2), status, ierr)
429 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
430 * 'persistent send/recv')
433 send_buf(i) = recv_buf(i)
436 call MPI_Start(requests(1), ierr)
437 call MPI_Wait(requests(1), status, ierr)
441 call MPI_Request_free(requests(1), ierr)
442 call MPI_Request_free(requests(2), ierr)
444 c Persistent ready sends
446 if (rank .eq. 0) then
447 print *, ' Rsend_init'
451 count = TEST_SIZE / 3
453 call clear_test_data(recv_buf,TEST_SIZE)
455 call MPI_Rsend_init(send_buf, count, MPI_REAL, next, tag,
456 . MPI_COMM_WORLD, requests(1), ierr)
458 call MPI_Recv_init(recv_buf, TEST_SIZE, MPI_REAL,
459 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
462 if (rank .eq. 0) then
464 call init_test_data(send_buf,TEST_SIZE)
466 call MPI_Recv( MPI_BOTTOM, 0, MPI_INTEGER, next, tag,
467 . MPI_COMM_WORLD, status, ierr )
469 call MPI_Startall(2, requests, ierr)
473 do while (index .ne. 2)
474 call MPI_Waitsome(2, requests, outcount,
475 . indices, statuses, ierr)
477 if (indices(i) .eq. 2) then
478 call msg_check( recv_buf, prev, tag, count,
479 $ statuses(1,i), TEST_SIZE, 'waitsome' )
487 call MPI_Start(requests(2), ierr)
489 call MPI_Send( MPI_BOTTOM, 0, MPI_INTEGER, next, tag,
490 . MPI_COMM_WORLD, ierr )
493 do while (.not. flag)
494 call MPI_Test(requests(2), flag, status, ierr)
496 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
500 send_buf(i) = recv_buf(i)
503 call MPI_Start(requests(1), ierr)
504 call MPI_Wait(requests(1), status, ierr)
508 call MPI_Request_free(requests(1), ierr)
509 call MPI_Request_free(requests(2), ierr)
511 c Persistent synchronous sends
513 if (rank .eq. 0) then
514 print *, ' Ssend_init'
518 count = TEST_SIZE / 3
520 call clear_test_data(recv_buf,TEST_SIZE)
522 call MPI_Ssend_init(send_buf, count, MPI_REAL, next, tag,
523 . MPI_COMM_WORLD, requests(2), ierr)
525 call MPI_Recv_init(recv_buf, TEST_SIZE, MPI_REAL,
526 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
529 if (rank .eq. 0) then
531 call init_test_data(send_buf,TEST_SIZE)
533 call MPI_Startall(2, requests, ierr)
536 do while (index .ne. 1)
537 call MPI_Testsome(2, requests, outcount,
538 . indices, statuses, ierr)
540 if (indices(i) .eq. 1) then
541 call msg_check( recv_buf, prev, tag, count,
542 $ statuses(1,i), TEST_SIZE, 'testsome' )
549 call MPI_Start(requests(1), ierr)
552 do while (.not. flag)
553 call MPI_Testany(1, requests(1), index, flag,
554 . statuses(1,1), ierr)
556 call msg_check( recv_buf, prev, tag, count, statuses(1,1),
557 $ TEST_SIZE, 'testany' )
560 send_buf(i) = recv_buf(i)
563 call MPI_Start(requests(2), ierr)
564 call MPI_Wait(requests(2), status, ierr)
568 call MPI_Request_free(requests(1), ierr)
569 call MPI_Request_free(requests(2), ierr)
573 if (rank .eq. 0) then
578 count = TEST_SIZE / 5
580 call clear_test_data(recv_buf,TEST_SIZE)
582 if (rank .eq. 0) then
584 call init_test_data(send_buf,TEST_SIZE)
586 call MPI_Sendrecv(send_buf, count, MPI_REAL, next, tag,
587 . recv_buf, count, MPI_REAL, prev, tag,
588 . MPI_COMM_WORLD, status, ierr)
590 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
595 call MPI_Recv(recv_buf, TEST_SIZE, MPI_REAL,
596 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
599 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
602 call MPI_Send(recv_buf, count, MPI_REAL, next, tag,
603 . MPI_COMM_WORLD, ierr)
606 c Send/receive replace.
608 if (rank .eq. 0) then
609 print *, ' Sendrecv_replace'
613 count = TEST_SIZE / 3
615 if (rank .eq. 0) then
617 call init_test_data(recv_buf, TEST_SIZE)
619 do 11 i = count+1,TEST_SIZE
623 call MPI_Sendrecv_replace(recv_buf, count, MPI_REAL,
624 . next, tag, prev, tag,
625 . MPI_COMM_WORLD, status, ierr)
627 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
628 . 'sendrecvreplace' )
632 call clear_test_data(recv_buf,TEST_SIZE)
634 call MPI_Recv(recv_buf, TEST_SIZE, MPI_REAL,
635 . MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
638 call msg_check( recv_buf, prev, tag, count, status, TEST_SIZE,
639 . 'recv/send for replace' )
641 call MPI_Send(recv_buf, count, MPI_REAL, next, tag,
642 . MPI_COMM_WORLD, ierr)
645 call MPI_Comm_free( dupcom, ierr )
649 c------------------------------------------------------------------------------
651 c Check for correct source, tag, count, and data in test message.
653 c------------------------------------------------------------------------------
654 subroutine msg_check( recv_buf, source, tag, count, status, n,
659 integer source, tag, count, rank, status(MPI_STATUS_SIZE)
662 integer ierr, recv_src, recv_tag, recv_count
664 recv_src = status(MPI_SOURCE)
665 recv_tag = status(MPI_TAG)
666 call MPI_Comm_rank( MPI_COMM_WORLD, rank, ierr )
667 call MPI_Get_count(status, MPI_REAL, recv_count, ierr)
669 if (recv_src .ne. source) then
670 print *, '[', rank, '] Unexpected source:', recv_src,
672 call MPI_Abort(MPI_COMM_WORLD, 101, ierr)
675 if (recv_tag .ne. tag) then
676 print *, '[', rank, '] Unexpected tag:', recv_tag, ' in ', name
677 call MPI_Abort(MPI_COMM_WORLD, 102, ierr)
680 if (recv_count .ne. count) then
681 print *, '[', rank, '] Unexpected count:', recv_count,
683 call MPI_Abort(MPI_COMM_WORLD, 103, ierr)
686 call verify_test_data(recv_buf, count, n, name )
689 c------------------------------------------------------------------------------
691 c Check that requests have been set to null
693 c------------------------------------------------------------------------------
694 subroutine rq_check( requests, n, msg )
696 integer n, requests(n)
701 if (requests(i) .ne. MPI_REQUEST_NULL) then
702 print *, 'Nonnull request in ', msg
707 c------------------------------------------------------------------------------
709 c Initialize test data buffer with integral sequence.
711 c------------------------------------------------------------------------------
712 subroutine init_test_data(buf,n)
722 c------------------------------------------------------------------------------
724 c Clear test data buffer
726 c------------------------------------------------------------------------------
727 subroutine clear_test_data(buf, n)
738 c------------------------------------------------------------------------------
740 c Verify test data buffer
742 c------------------------------------------------------------------------------
743 subroutine verify_test_data(buf, count, n, name)
749 integer count, ierr, i
752 if (buf(i) .ne. REAL(i)) then
753 print 100, buf(i), i, count, name
754 call MPI_Abort(MPI_COMM_WORLD, 108, ierr)
758 do 20 i = count + 1, n
759 if (buf(i) .ne. 0.) then
760 print 100, buf(i), i, n, name
761 call MPI_Abort(MPI_COMM_WORLD, 109, ierr)
765 100 format('Invalid data', f6.1, ' at ', i4, ' of ', i4, ' in ', a)