44 send_blocks, recv_blocks)
45 INTEGER,
DIMENSION(0:),
INTENT(IN) :: send_count, recv_count
46 INTEGER,
INTENT(IN) :: n_index
48 INTEGER,
DIMENSION(0:),
INTENT(IN),
OPTIONAL :: send_blocks, recv_blocks
50 INTEGER :: nprocs, peer
52 cpassert(
PRESENT(send_blocks) .EQV.
PRESENT(recv_blocks))
53 nprocs =
SIZE(send_count)
54 ALLOCATE (buffer_send%msg_offset(0:nprocs), buffer_rec%msg_offset(0:nprocs), &
55 buffer_send%indx_offset(0:nprocs), buffer_rec%indx_offset(0:nprocs))
56 buffer_send%msg_offset(0) = 0
57 buffer_rec%msg_offset(0) = 0
58 buffer_send%indx_offset(0) = 0
59 buffer_rec%indx_offset(0) = 0
60 DO peer = 0, nprocs - 1
61 buffer_send%msg_offset(peer + 1) = buffer_send%msg_offset(peer) + send_count(peer)
62 buffer_rec%msg_offset(peer + 1) = buffer_rec%msg_offset(peer) + recv_count(peer)
63 buffer_send%indx_offset(peer + 1) = buffer_send%indx_offset(peer) + send_count(peer)
64 buffer_rec%indx_offset(peer + 1) = buffer_rec%indx_offset(peer) + recv_count(peer)
65 IF (
PRESENT(send_blocks))
THEN
66 buffer_send%indx_offset(peer + 1) = buffer_send%indx_offset(peer) + send_blocks(peer)
67 buffer_rec%indx_offset(peer + 1) = buffer_rec%indx_offset(peer) + recv_blocks(peer)
70 ALLOCATE (buffer_send%msg(buffer_send%msg_offset(nprocs)), &
71 buffer_rec%msg(buffer_rec%msg_offset(nprocs)), &
72 buffer_send%indx(n_index, buffer_send%indx_offset(nprocs)), &
73 buffer_rec%indx(n_index, buffer_rec%indx_offset(nprocs)))
87 LOGICAL,
INTENT(IN),
OPTIONAL :: do_indx, do_msg
89 CHARACTER(LEN=*),
PARAMETER :: routinen =
'exchange_matrix_buffers'
91 INTEGER :: first, handle, last, nprocs, nreq, peer
92 LOGICAL :: my_do_indx, my_do_msg
95 CALL timeset(routinen, handle)
98 IF (
PRESENT(do_indx)) my_do_indx = do_indx
100 IF (
PRESENT(do_msg)) my_do_msg = do_msg
105 buffer_rec%indx(:, buffer_rec%indx_offset(peer) + 1:buffer_rec%indx_offset(peer + 1)) = &
106 buffer_send%indx(:, buffer_send%indx_offset(peer) + 1:buffer_send%indx_offset(peer + 1))
109 buffer_rec%msg(buffer_rec%msg_offset(peer) + 1:buffer_rec%msg_offset(peer + 1)) = &
110 buffer_send%msg(buffer_send%msg_offset(peer) + 1:buffer_send%msg_offset(peer + 1))
116 nreq = count(buffer_rec%indx_offset(1:) > buffer_rec%indx_offset(:nprocs - 1)) + &
117 count(buffer_send%indx_offset(1:) > buffer_send%indx_offset(:nprocs - 1))
120 nreq = nreq + count(buffer_rec%msg_offset(1:) > buffer_rec%msg_offset(:nprocs - 1)) + &
121 count(buffer_send%msg_offset(1:) > buffer_send%msg_offset(:nprocs - 1))
123 ALLOCATE (requests(nreq))
127 DO peer = 0, nprocs - 1
128 IF (peer == comm%mepos) cycle
130 first = buffer_rec%indx_offset(peer) + 1
131 last = buffer_rec%indx_offset(peer + 1)
132 IF (last >= first)
THEN
134 CALL comm%irecv(buffer_rec%indx(:, first:last), peer, requests(nreq), tag=4)
137 IF (my_do_msg .AND. buffer_rec%msg_offset(peer + 1) > buffer_rec%msg_offset(peer))
THEN
138 first = buffer_rec%msg_offset(peer) + 1
139 last = buffer_rec%msg_offset(peer + 1)
141 CALL comm%irecv(buffer_rec%msg(first:last), peer, requests(nreq), tag=7)
145 DO peer = 0, nprocs - 1
146 IF (peer == comm%mepos) cycle
148 first = buffer_send%indx_offset(peer) + 1
149 last = buffer_send%indx_offset(peer + 1)
150 IF (last >= first)
THEN
152 CALL comm%isend(buffer_send%indx(:, first:last), peer, requests(nreq), tag=4)
155 IF (my_do_msg .AND. buffer_send%msg_offset(peer + 1) > buffer_send%msg_offset(peer))
THEN
156 first = buffer_send%msg_offset(peer) + 1
157 last = buffer_send%msg_offset(peer + 1)
159 CALL comm%isend(buffer_send%msg(first:last), peer, requests(nreq), tag=7)
162 IF (nreq > 0)
CALL mp_waitall(requests(:nreq))
164 CALL timestop(handle)
subroutine, public allocate_matrix_buffers(send_count, recv_count, n_index, buffer_send, buffer_rec, send_blocks, recv_blocks)
Allocate flat, rank-grouped matrix buffers and their zero-based offsets.