50 SUBROUTINE dbt_reshape(tensor_in, tensor_out, summation, move_data, bounds)
52 TYPE(
dbt_type),
INTENT(INOUT) :: tensor_in, tensor_out
53 LOGICAL,
INTENT(IN),
OPTIONAL :: summation
54 LOGICAL,
INTENT(IN),
OPTIONAL :: move_data
55 INTEGER,
DIMENSION(2, ndims_tensor(tensor_in)),
INTENT(IN),
OPTIONAL :: bounds
57 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbt_reshape'
59 INTEGER :: iproc, numnodes, nindex, &
60 handle, handle2, iblk, offset, ndata
61 INTEGER,
DIMENSION(2) :: block_range
63 CHARACTER(LEN=32) :: name_pack, name_unpack
64 INTEGER,
DIMENSION(ndims_tensor(tensor_in)) :: blk_size, blk_offset, ind_nd
65 INTEGER,
DIMENSION(2, ndims_tensor(tensor_in)) :: bounds_prv
66 LOGICAL :: found, summation_prv, move_prv, do_bounds, overlap, inside
68 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: nblks_send_total, ndata_send_total, &
69 nblks_recv_total, ndata_recv_total, &
70 nblks_send_mythread, ndata_send_mythread
73 CALL timeset(routinen, handle)
75 IF (
PRESENT(summation))
THEN
76 summation_prv = summation
78 summation_prv = .false.
81 IF (
PRESENT(move_data))
THEN
87 do_bounds =
PRESENT(bounds)
89 bounds_prv(:, :) = bounds(:, :)
94 cpassert(tensor_out%valid)
96 IF (.NOT. summation_prv)
THEN
97 CALL timeset(routinen//
"_clear", handle2)
99 CALL timestop(handle2)
102 mp_comm = tensor_in%pgrid%mp_comm_2d
103 numnodes = mp_comm%num_pe
106 name_pack = routinen//
"_pack"
107 IF (permuted(tensor_in)) name_pack = routinen//
"_pack_perm"
108 name_unpack = routinen//
"_unpack"
109 IF (permuted(tensor_out)) name_unpack = routinen//
"_unpack_perm"
110 ALLOCATE (nblks_send_total(0:numnodes - 1), ndata_send_total(0:numnodes - 1), source=0)
111 ALLOCATE (nblks_recv_total(0:numnodes - 1), ndata_recv_total(0:numnodes - 1), source=0)
120 CALL timeset(routinen//
"_count", handle2)
121 ALLOCATE (nblks_send_mythread(0:numnodes - 1), ndata_send_mythread(0:numnodes - 1), source=0)
127 CALL block_bounds(bounds_prv, blk_offset, blk_size, overlap, inside)
128 IF (.NOT. overlap) cycle
131 nblks_send_mythread(iproc) = nblks_send_mythread(iproc) + 1
132 ndata_send_mythread(iproc) = ndata_send_mythread(iproc) + product(blk_size)
136 nblks_send_total(:) = nblks_send_total(:) + nblks_send_mythread(:)
137 ndata_send_total(:) = ndata_send_total(:) + ndata_send_mythread(:)
138 nblks_send_mythread(:) = nblks_send_total(:)
139 ndata_send_mythread(:) = ndata_send_total(:)
144 CALL mp_comm%alltoall(nblks_send_total, nblks_recv_total, 1)
145 CALL mp_comm%alltoall(ndata_send_total, ndata_recv_total, 1)
148 CALL timestop(handle2)
150 CALL timeset(trim(name_pack), handle2)
152 CALL grow_buffer(buffer_send, ndata_send_total, nblks_send_total, nindex)
153 CALL grow_buffer(buffer_recv, ndata_recv_total, nblks_recv_total, nindex)
162 CALL block_bounds(bounds_prv, blk_offset, blk_size, overlap, inside)
163 IF (.NOT. overlap) cycle
167 ndata = product(blk_size)
168 ndata_send_mythread(iproc) = ndata_send_mythread(iproc) - ndata
169 offset = buffer_send%msg_offset(iproc) + ndata_send_mythread(iproc)
170 CALL dbt_get_block_data(tensor_in, ind_nd, blk_size, buffer_send%msg(offset + 1:offset + ndata), found)
172 IF (.NOT. inside)
CALL block_crop(bounds_prv, blk_offset, blk_size, buffer_send%msg(offset + 1:offset + ndata))
174 nblks_send_mythread(iproc) = nblks_send_mythread(iproc) - 1
175 iblk = buffer_send%indx_offset(iproc) + nblks_send_mythread(iproc) + 1
176 buffer_send%indx(2:, iblk) = ind_nd(:)
178 buffer_send%indx(1, iblk) = ndata_send_mythread(iproc)
181 DEALLOCATE (nblks_send_mythread, ndata_send_mythread)
183 CALL timestop(handle2)
186 IF (numnodes > 1)
THEN
190 CALL swap_buffers(buffer_send, buffer_recv)
195 CALL timeset(routinen//
"_reserve", handle2)
196 block_range =
get_limit(buffer_recv%indx_offset(numnodes), omp_get_num_threads(), omp_get_thread_num())
197 CALL dbt_reserve_blocks(tensor_out, transpose(buffer_recv%indx(2:, block_range(1):block_range(2))))
199 CALL timestop(handle2)
201 CALL timeset(trim(name_unpack), handle2)
202 DO iproc = 0, numnodes - 1
204 DO iblk = buffer_recv%indx_offset(iproc) + 1, buffer_recv%indx_offset(iproc + 1)
205 ind_nd(:) = buffer_recv%indx(2:, iblk)
207 offset = buffer_recv%msg_offset(iproc) + buffer_recv%indx(1, iblk)
208 ndata = product(blk_size)
209 CALL dbt_put_block_data(tensor_out, ind_nd, blk_size, buffer_recv%msg(offset + 1:offset + ndata), &
214 CALL timestop(handle2)
217 DEALLOCATE (nblks_recv_total, ndata_recv_total)
218 DEALLOCATE (nblks_send_total, ndata_send_total)
221 CALL timeset(routinen//
"_clear", handle2)
223 CALL timestop(handle2)
226 CALL timestop(handle)