80 homo, virtual, mo_coeff_o, ngroup, my_group_L_start, my_group_L_end, &
82 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_mat_gamma_3
83 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: dbcsr_gamma_3
86 INTEGER,
INTENT(IN) :: homo, virtual
87 TYPE(dbcsr_type),
POINTER :: mo_coeff_o
88 INTEGER,
INTENT(IN) :: ngroup, my_group_l_start, &
89 my_group_l_end, my_group_l_size
91 CHARACTER(LEN=*),
PARAMETER :: routinen =
'gamma_fm_to_dbcsr'
93 INTEGER :: dimen_ia, dummy_proc, handle, i_global, i_local, iaia, iib, iii, itmp(2), &
94 j_global, j_local, jjb, jjj, kkb, my_ia_end, my_ia_size, my_ia_start, mypcol, myprow, &
95 ncol_block, ncol_local, npcol, nprow, nrow_block, nrow_local, number_of_rec, &
96 number_of_send, proc_receive, proc_send, proc_shift, rec_counter, rec_iaia_end, &
97 rec_iaia_size, rec_iaia_start, rec_pcol, rec_prow, ref_send_pcol, ref_send_prow, &
98 send_counter, send_pcol, send_prow, size_rec_buffer, size_send_buffer
99 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iii_vet, map_rec_size, map_send_size
100 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: grid_2_mepos, grid_ref_2_send_pos, &
101 group_grid_2_mepos, indices_map_my, &
102 mepos_2_grid, mepos_2_grid_group
103 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
104 REAL(kind=
dp) :: part_ia
105 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: gamma_2d
110 TYPE(index_map),
ALLOCATABLE,
DIMENSION(:) :: indices_rec
112 DIMENSION(:) :: buffer_rec, buffer_send
115 CALL timeset(routinen, handle)
117 dimen_ia = virtual*homo
121 CALL get_group_dist(gd_ia, para_env_sub%mepos, my_ia_start, my_ia_end, my_ia_size)
126 group_grid_2_mepos, mepos_2_grid_group)
129 CALL fm2array(gamma_2d, my_ia_size, my_ia_start, my_ia_end, &
130 my_group_l_size, my_group_l_start, my_group_l_end, &
131 group_grid_2_mepos, mepos_2_grid_group, &
132 para_env_sub%num_pe, ngroup, &
142 ncol_global=virtual, para_env=para_env_sub)
152 nrow_local=nrow_local, &
153 ncol_local=ncol_local, &
154 row_indices=row_indices, &
155 col_indices=col_indices, &
156 nrow_block=nrow_block, &
157 ncol_block=ncol_block)
158 myprow = fm_ia%matrix_struct%context%mepos(1)
159 mypcol = fm_ia%matrix_struct%context%mepos(2)
160 nprow = fm_ia%matrix_struct%context%num_pe(1)
161 npcol = fm_ia%matrix_struct%context%num_pe(2)
164 ALLOCATE (grid_2_mepos(0:nprow - 1, 0:npcol - 1))
166 ALLOCATE (mepos_2_grid(2, 0:para_env_sub%num_pe - 1))
168 grid_2_mepos(myprow, mypcol) = para_env_sub%mepos
170 CALL para_env_sub%sum(grid_2_mepos)
171 CALL para_env_sub%allgather([myprow, mypcol], mepos_2_grid)
174 ALLOCATE (map_send_size(0:para_env_sub%num_pe - 1))
177 DO iaia = my_ia_start, my_ia_end
178 i_global = (iaia - 1)/virtual + 1
179 j_global = mod(iaia - 1, virtual) + 1
180 send_prow =
cp_fm_indxg2p(i_global, nrow_block, dummy_proc, &
181 fm_ia%matrix_struct%first_p_pos(1), nprow)
182 send_pcol =
cp_fm_indxg2p(j_global, ncol_block, dummy_proc, &
183 fm_ia%matrix_struct%first_p_pos(2), npcol)
184 proc_send = grid_2_mepos(send_prow, send_pcol)
185 map_send_size(proc_send) = map_send_size(proc_send) + 1
189 ALLOCATE (map_rec_size(0:para_env_sub%num_pe - 1))
191 part_ia = real(dimen_ia, kind=
dp)/real(para_env_sub%num_pe, kind=
dp)
193 DO iib = 1, nrow_local
194 i_global = row_indices(iib)
195 DO jjb = 1, ncol_local
196 j_global = col_indices(jjb)
197 iaia = (i_global - 1)*virtual + j_global
198 proc_receive = int(real(iaia - 1, kind=
dp)/part_ia)
199 proc_receive = max(0, proc_receive)
200 proc_receive = min(proc_receive, para_env_sub%num_pe - 1)
202 itmp =
get_limit(dimen_ia, para_env_sub%num_pe, proc_receive)
203 IF (iaia >= itmp(1) .AND. iaia <= itmp(2))
EXIT
204 IF (iaia < itmp(1)) proc_receive = proc_receive - 1
205 IF (iaia > itmp(2)) proc_receive = proc_receive + 1
207 map_rec_size(proc_receive) = map_rec_size(proc_receive) + 1
213 DO proc_shift = 1, para_env_sub%num_pe - 1
214 proc_send =
modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
215 IF (map_send_size(proc_send) > 0)
THEN
216 number_of_send = number_of_send + 1
220 ALLOCATE (buffer_send(number_of_send))
222 ALLOCATE (grid_ref_2_send_pos(0:nprow - 1, 0:npcol - 1))
223 grid_ref_2_send_pos = 0
226 DO proc_shift = 1, para_env_sub%num_pe - 1
227 proc_send =
modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
228 size_send_buffer = map_send_size(proc_send)
229 IF (map_send_size(proc_send) > 0)
THEN
230 send_counter = send_counter + 1
232 ALLOCATE (buffer_send(send_counter)%msg(size_send_buffer))
233 buffer_send(send_counter)%proc = proc_send
236 ref_send_prow = mepos_2_grid(1, proc_send)
237 ref_send_pcol = mepos_2_grid(2, proc_send)
239 grid_ref_2_send_pos(ref_send_prow, ref_send_pcol) = send_counter
245 DO proc_shift = 1, para_env_sub%num_pe - 1
246 proc_receive =
modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
247 IF (map_rec_size(proc_receive) > 0)
THEN
248 number_of_rec = number_of_rec + 1
254 ALLOCATE (buffer_rec(number_of_rec))
255 ALLOCATE (indices_rec(number_of_rec))
258 DO proc_shift = 1, para_env_sub%num_pe - 1
259 proc_receive =
modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
260 size_rec_buffer = map_rec_size(proc_receive)
261 IF (map_rec_size(proc_receive) > 0)
THEN
262 rec_counter = rec_counter + 1
264 ALLOCATE (buffer_rec(rec_counter)%msg(size_rec_buffer))
265 buffer_rec(rec_counter)%proc = proc_receive
267 ALLOCATE (indices_rec(rec_counter)%map(2, size_rec_buffer))
268 indices_rec(rec_counter)%map = 0
269 CALL get_group_dist(gd_ia, proc_receive, rec_iaia_start, rec_iaia_end, rec_iaia_size)
271 DO iaia = rec_iaia_start, rec_iaia_end
272 i_global = (iaia - 1)/virtual + 1
273 j_global = mod(iaia - 1, virtual) + 1
275 fm_ia%matrix_struct%first_p_pos(1), nprow)
277 fm_ia%matrix_struct%first_p_pos(2), npcol)
278 IF (grid_2_mepos(rec_prow, rec_pcol) /= para_env_sub%mepos) cycle
281 fm_ia%matrix_struct%first_p_pos(1), nprow)
283 fm_ia%matrix_struct%first_p_pos(2), npcol)
284 indices_rec(rec_counter)%map(1, iii) = i_local
285 indices_rec(rec_counter)%map(2, iii) = j_local
291 IF (map_rec_size(para_env_sub%mepos) > 0)
THEN
292 size_rec_buffer = map_rec_size(para_env_sub%mepos)
293 ALLOCATE (indices_map_my(2, size_rec_buffer))
296 DO iaia = my_ia_start, my_ia_end
297 i_global = (iaia - 1)/virtual + 1
298 j_global = mod(iaia - 1, virtual) + 1
300 fm_ia%matrix_struct%first_p_pos(1), nprow)
302 fm_ia%matrix_struct%first_p_pos(2), npcol)
303 IF (grid_2_mepos(rec_prow, rec_pcol) /= para_env_sub%mepos) cycle
306 fm_ia%matrix_struct%first_p_pos(1), nprow)
308 fm_ia%matrix_struct%first_p_pos(2), npcol)
309 indices_map_my(1, iii) = i_local
310 indices_map_my(2, iii) = j_local
315 NULLIFY (dbcsr_gamma_3)
321 ALLOCATE (iii_vet(number_of_send))
323 ALLOCATE (req_send(number_of_send))
328 DO kkb = 1, my_group_l_size
332 DO proc_shift = 1, para_env_sub%num_pe - 1
333 proc_receive =
modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
334 IF (map_rec_size(proc_receive) > 0)
THEN
335 rec_counter = rec_counter + 1
336 buffer_rec(rec_counter)%msg = 0.0_dp
337 CALL para_env_sub%irecv(buffer_rec(rec_counter)%msg, proc_receive, &
338 buffer_rec(rec_counter)%msg_req)
342 DO send_counter = 1, number_of_send
343 buffer_send(send_counter)%msg = 0.0_dp
347 DO iaia = my_ia_start, my_ia_end
348 i_global = (iaia - 1)/virtual + 1
349 j_global = mod(iaia - 1, virtual) + 1
350 send_prow =
cp_fm_indxg2p(i_global, nrow_block, dummy_proc, &
351 fm_ia%matrix_struct%first_p_pos(1), nprow)
352 send_pcol =
cp_fm_indxg2p(j_global, ncol_block, dummy_proc, &
353 fm_ia%matrix_struct%first_p_pos(2), npcol)
354 proc_send = grid_2_mepos(send_prow, send_pcol)
356 IF (grid_2_mepos(send_prow, send_pcol) == para_env_sub%mepos)
THEN
359 i_local = indices_map_my(1, jjj)
360 j_local = indices_map_my(2, jjj)
361 fm_ia%local_data(i_local, j_local) = &
362 gamma_2d(iaia - my_ia_start + 1, kkb)
365 send_counter = grid_ref_2_send_pos(send_prow, send_pcol)
366 iii_vet(send_counter) = iii_vet(send_counter) + 1
367 iii = iii_vet(send_counter)
368 buffer_send(send_counter)%msg(iii) = &
369 gamma_2d(iaia - my_ia_start + 1, kkb)
374 DO proc_shift = 1, para_env_sub%num_pe - 1
375 proc_send =
modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
376 IF (map_send_size(proc_send) > 0)
THEN
377 send_counter = send_counter + 1
378 CALL para_env_sub%isend(buffer_send(send_counter)%msg, proc_send, &
379 buffer_send(send_counter)%msg_req)
380 req_send(send_counter) = buffer_send(send_counter)%msg_req
386 DO proc_shift = 1, para_env_sub%num_pe - 1
387 proc_receive =
modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
388 size_rec_buffer = map_rec_size(proc_receive)
389 IF (map_rec_size(proc_receive) > 0)
THEN
390 rec_counter = rec_counter + 1
392 CALL buffer_rec(rec_counter)%msg_req%wait()
393 DO iii = 1, size_rec_buffer
394 i_local = indices_rec(rec_counter)%map(1, iii)
395 j_local = indices_rec(rec_counter)%map(2, iii)
396 fm_ia%local_data(i_local, j_local) = buffer_rec(rec_counter)%msg(iii)
405 ALLOCATE (dbcsr_gamma_3(kkb)%matrix)
407 template=mo_coeff_o, &
408 m=homo, n=virtual, sym=dbcsr_type_no_symmetry)
409 CALL copy_fm_to_dbcsr(fm_ia, dbcsr_gamma_3(kkb)%matrix, keep_sparsity=.false.)
415 DEALLOCATE (gamma_2d)
417 DEALLOCATE (req_send)
418 IF (map_rec_size(para_env_sub%mepos) > 0)
THEN
419 DEALLOCATE (indices_map_my)
421 DO rec_counter = 1, number_of_rec
422 DEALLOCATE (indices_rec(rec_counter)%map)
423 DEALLOCATE (buffer_rec(rec_counter)%msg)
425 DEALLOCATE (indices_rec)
426 DEALLOCATE (buffer_rec)
427 DO send_counter = 1, number_of_send
428 DEALLOCATE (buffer_send(send_counter)%msg)
430 DEALLOCATE (buffer_send)
431 DEALLOCATE (map_send_size)
432 DEALLOCATE (map_rec_size)
433 DEALLOCATE (grid_2_mepos)
434 DEALLOCATE (mepos_2_grid)
440 CALL timestop(handle)