76 homo, virtual, mo_coeff_o, ngroup, my_group_L_start, my_group_L_end, &
78 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_mat_gamma_3
79 TYPE(
dbcsr_type),
ALLOCATABLE,
DIMENSION(:) :: dbcsr_gamma_3
82 INTEGER,
INTENT(IN) :: homo, virtual
84 INTEGER,
INTENT(IN) :: ngroup, my_group_l_start, &
85 my_group_l_end, my_group_l_size
87 CHARACTER(LEN=*),
PARAMETER :: routinen =
'gamma_fm_to_dbcsr'
89 INTEGER :: dimen_ia, dummy_proc, handle, i_global, i_local, iaia, iib, iii, itmp(2), &
90 j_global, j_local, jjb, jjj, kkb, my_ia_end, my_ia_size, my_ia_start, mypcol, myprow, &
91 ncol_local, npcol, nprow, nrow_local, number_of_rec, number_of_send, proc_receive, &
92 proc_send, proc_shift, rec_counter, rec_iaia_end, rec_iaia_size, rec_iaia_start, &
93 rec_pcol, rec_prow, ref_send_pcol, ref_send_prow, send_counter, send_pcol, send_prow, &
94 size_rec_buffer, size_send_buffer
95 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iii_vet, map_rec_size, map_send_size
96 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: grid_2_mepos, grid_ref_2_send_pos, &
97 group_grid_2_mepos, indices_map_my, &
98 mepos_2_grid, mepos_2_grid_group
99 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
100 REAL(kind=
dp) :: part_ia
101 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: gamma_2d
106 TYPE(index_map),
ALLOCATABLE,
DIMENSION(:) :: indices_rec
108 DIMENSION(:) :: buffer_rec, buffer_send
111 CALL timeset(routinen, handle)
113 dimen_ia = virtual*homo
117 CALL get_group_dist(gd_ia, para_env_sub%mepos, my_ia_start, my_ia_end, my_ia_size)
122 group_grid_2_mepos, mepos_2_grid_group)
125 CALL fm2array(gamma_2d, my_ia_size, my_ia_start, my_ia_end, &
126 my_group_l_size, my_group_l_start, my_group_l_end, &
127 group_grid_2_mepos, mepos_2_grid_group, &
128 para_env_sub%num_pe, ngroup, &
138 ncol_global=virtual, para_env=para_env_sub)
148 nrow_local=nrow_local, &
149 ncol_local=ncol_local, &
150 row_indices=row_indices, &
151 col_indices=col_indices)
152 myprow = fm_ia%matrix_struct%context%mepos(1)
153 mypcol = fm_ia%matrix_struct%context%mepos(2)
154 nprow = fm_ia%matrix_struct%context%num_pe(1)
155 npcol = fm_ia%matrix_struct%context%num_pe(2)
158 ALLOCATE (grid_2_mepos(0:nprow - 1, 0:npcol - 1))
160 ALLOCATE (mepos_2_grid(2, 0:para_env_sub%num_pe - 1))
162 grid_2_mepos(myprow, mypcol) = para_env_sub%mepos
164 CALL para_env_sub%sum(grid_2_mepos)
165 CALL para_env_sub%allgather([myprow, mypcol], mepos_2_grid)
168 ALLOCATE (map_send_size(0:para_env_sub%num_pe - 1))
171 DO iaia = my_ia_start, my_ia_end
172 i_global = (iaia - 1)/virtual + 1
173 j_global = mod(iaia - 1, virtual) + 1
174 send_prow = fm_ia%matrix_struct%g2p_row(i_global)
175 send_pcol = fm_ia%matrix_struct%g2p_col(j_global)
176 proc_send = grid_2_mepos(send_prow, send_pcol)
177 map_send_size(proc_send) = map_send_size(proc_send) + 1
181 ALLOCATE (map_rec_size(0:para_env_sub%num_pe - 1))
183 part_ia = real(dimen_ia, kind=
dp)/real(para_env_sub%num_pe, kind=
dp)
185 DO iib = 1, nrow_local
186 i_global = row_indices(iib)
187 DO jjb = 1, ncol_local
188 j_global = col_indices(jjb)
189 iaia = (i_global - 1)*virtual + j_global
190 proc_receive = int(real(iaia - 1, kind=
dp)/part_ia)
191 proc_receive = max(0, proc_receive)
192 proc_receive = min(proc_receive, para_env_sub%num_pe - 1)
194 itmp =
get_limit(dimen_ia, para_env_sub%num_pe, proc_receive)
195 IF (iaia >= itmp(1) .AND. iaia <= itmp(2))
EXIT
196 IF (iaia < itmp(1)) proc_receive = proc_receive - 1
197 IF (iaia > itmp(2)) proc_receive = proc_receive + 1
199 map_rec_size(proc_receive) = map_rec_size(proc_receive) + 1
205 DO proc_shift = 1, para_env_sub%num_pe - 1
206 proc_send =
modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
207 IF (map_send_size(proc_send) > 0)
THEN
208 number_of_send = number_of_send + 1
212 ALLOCATE (buffer_send(number_of_send))
214 ALLOCATE (grid_ref_2_send_pos(0:nprow - 1, 0:npcol - 1))
215 grid_ref_2_send_pos = 0
218 DO proc_shift = 1, para_env_sub%num_pe - 1
219 proc_send =
modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
220 size_send_buffer = map_send_size(proc_send)
221 IF (map_send_size(proc_send) > 0)
THEN
222 send_counter = send_counter + 1
224 ALLOCATE (buffer_send(send_counter)%msg(size_send_buffer))
225 buffer_send(send_counter)%proc = proc_send
228 ref_send_prow = mepos_2_grid(1, proc_send)
229 ref_send_pcol = mepos_2_grid(2, proc_send)
231 grid_ref_2_send_pos(ref_send_prow, ref_send_pcol) = send_counter
237 DO proc_shift = 1, para_env_sub%num_pe - 1
238 proc_receive =
modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
239 IF (map_rec_size(proc_receive) > 0)
THEN
240 number_of_rec = number_of_rec + 1
246 ALLOCATE (buffer_rec(number_of_rec))
247 ALLOCATE (indices_rec(number_of_rec))
250 DO proc_shift = 1, para_env_sub%num_pe - 1
251 proc_receive =
modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
252 size_rec_buffer = map_rec_size(proc_receive)
253 IF (map_rec_size(proc_receive) > 0)
THEN
254 rec_counter = rec_counter + 1
256 ALLOCATE (buffer_rec(rec_counter)%msg(size_rec_buffer))
257 buffer_rec(rec_counter)%proc = proc_receive
259 ALLOCATE (indices_rec(rec_counter)%map(2, size_rec_buffer))
260 indices_rec(rec_counter)%map = 0
261 CALL get_group_dist(gd_ia, proc_receive, rec_iaia_start, rec_iaia_end, rec_iaia_size)
263 DO iaia = rec_iaia_start, rec_iaia_end
264 i_global = (iaia - 1)/virtual + 1
265 j_global = mod(iaia - 1, virtual) + 1
266 rec_prow = fm_ia%matrix_struct%g2p_row(i_global)
267 rec_pcol = fm_ia%matrix_struct%g2p_col(j_global)
268 IF (grid_2_mepos(rec_prow, rec_pcol) /= para_env_sub%mepos) cycle
270 i_local = fm_ia%matrix_struct%g2l_row(i_global)
271 j_local = fm_ia%matrix_struct%g2l_col(j_global)
272 indices_rec(rec_counter)%map(1, iii) = i_local
273 indices_rec(rec_counter)%map(2, iii) = j_local
279 IF (map_rec_size(para_env_sub%mepos) > 0)
THEN
280 size_rec_buffer = map_rec_size(para_env_sub%mepos)
281 ALLOCATE (indices_map_my(2, size_rec_buffer))
284 DO iaia = my_ia_start, my_ia_end
285 i_global = (iaia - 1)/virtual + 1
286 j_global = mod(iaia - 1, virtual) + 1
287 rec_prow = fm_ia%matrix_struct%g2p_row(i_global)
288 rec_pcol = fm_ia%matrix_struct%g2p_col(j_global)
289 IF (grid_2_mepos(rec_prow, rec_pcol) /= para_env_sub%mepos) cycle
291 i_local = fm_ia%matrix_struct%g2l_row(i_global)
292 j_local = fm_ia%matrix_struct%g2l_col(j_global)
293 indices_map_my(1, iii) = i_local
294 indices_map_my(2, iii) = j_local
299 ALLOCATE (dbcsr_gamma_3(my_group_l_size))
302 ALLOCATE (iii_vet(number_of_send))
304 ALLOCATE (req_send(number_of_send))
309 DO kkb = 1, my_group_l_size
313 DO proc_shift = 1, para_env_sub%num_pe - 1
314 proc_receive =
modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
315 IF (map_rec_size(proc_receive) > 0)
THEN
316 rec_counter = rec_counter + 1
317 buffer_rec(rec_counter)%msg = 0.0_dp
318 CALL para_env_sub%irecv(buffer_rec(rec_counter)%msg, proc_receive, &
319 buffer_rec(rec_counter)%msg_req)
323 DO send_counter = 1, number_of_send
324 buffer_send(send_counter)%msg = 0.0_dp
328 DO iaia = my_ia_start, my_ia_end
329 i_global = (iaia - 1)/virtual + 1
330 j_global = mod(iaia - 1, virtual) + 1
331 send_prow = fm_ia%matrix_struct%g2p_row(i_global)
332 send_pcol = fm_ia%matrix_struct%g2p_col(j_global)
333 proc_send = grid_2_mepos(send_prow, send_pcol)
335 IF (grid_2_mepos(send_prow, send_pcol) == para_env_sub%mepos)
THEN
338 i_local = indices_map_my(1, jjj)
339 j_local = indices_map_my(2, jjj)
340 fm_ia%local_data(i_local, j_local) = &
341 gamma_2d(iaia - my_ia_start + 1, kkb)
344 send_counter = grid_ref_2_send_pos(send_prow, send_pcol)
345 iii_vet(send_counter) = iii_vet(send_counter) + 1
346 iii = iii_vet(send_counter)
347 buffer_send(send_counter)%msg(iii) = &
348 gamma_2d(iaia - my_ia_start + 1, kkb)
353 DO proc_shift = 1, para_env_sub%num_pe - 1
354 proc_send =
modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
355 IF (map_send_size(proc_send) > 0)
THEN
356 send_counter = send_counter + 1
357 CALL para_env_sub%isend(buffer_send(send_counter)%msg, proc_send, &
358 buffer_send(send_counter)%msg_req)
359 req_send(send_counter) = buffer_send(send_counter)%msg_req
365 DO proc_shift = 1, para_env_sub%num_pe - 1
366 proc_receive =
modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
367 size_rec_buffer = map_rec_size(proc_receive)
368 IF (map_rec_size(proc_receive) > 0)
THEN
369 rec_counter = rec_counter + 1
371 CALL buffer_rec(rec_counter)%msg_req%wait()
372 DO iii = 1, size_rec_buffer
373 i_local = indices_rec(rec_counter)%map(1, iii)
374 j_local = indices_rec(rec_counter)%map(2, iii)
375 fm_ia%local_data(i_local, j_local) = buffer_rec(rec_counter)%msg(iii)
385 m=homo, n=virtual, sym=dbcsr_type_no_symmetry)
392 DEALLOCATE (gamma_2d)
394 DEALLOCATE (req_send)
395 IF (map_rec_size(para_env_sub%mepos) > 0)
THEN
396 DEALLOCATE (indices_map_my)
398 DO rec_counter = 1, number_of_rec
399 DEALLOCATE (indices_rec(rec_counter)%map)
400 DEALLOCATE (buffer_rec(rec_counter)%msg)
402 DEALLOCATE (indices_rec)
403 DEALLOCATE (buffer_rec)
404 DO send_counter = 1, number_of_send
405 DEALLOCATE (buffer_send(send_counter)%msg)
407 DEALLOCATE (buffer_send)
408 DEALLOCATE (map_send_size)
409 DEALLOCATE (map_rec_size)
410 DEALLOCATE (grid_2_mepos)
411 DEALLOCATE (mepos_2_grid)
417 CALL timestop(handle)