(git:374b731)
Loading...
Searching...
No Matches
gw_communication.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief
10!> \author Jan Wilhelm
11!> \date 08.2023
12! **************************************************************************************************
14 USE dbcsr_api, ONLY: &
15 dbcsr_copy, dbcsr_create, dbcsr_filter, dbcsr_finalize, dbcsr_get_info, &
16 dbcsr_get_stored_coordinates, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
17 dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_release, &
18 dbcsr_reserve_all_blocks, dbcsr_reserve_blocks, dbcsr_set, dbcsr_type
19 USE kinds, ONLY: dp
23#include "./base/base_uses.f90"
24
25 IMPLICIT NONE
26
27 PRIVATE
28
29 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'gw_communication'
30
32
33 TYPE buffer_type
34 REAL(KIND=dp), DIMENSION(:), POINTER :: msg => null()
35 INTEGER, DIMENSION(:), POINTER :: sizes => null()
36 INTEGER, DIMENSION(:, :), POINTER :: indx => null()
37 INTEGER :: proc = -1
38 INTEGER :: msg_req = -1
39 END TYPE
40
41CONTAINS
42
43! **************************************************************************************************
44!> \brief ...
45!> \param mat_global ...
46!> \param mat_local ...
47!> \param para_env ...
48!> \param num_pe_sub ...
49!> \param atom_ranges ...
50! **************************************************************************************************
51 SUBROUTINE global_matrix_to_local_matrix(mat_global, mat_local, para_env, num_pe_sub, atom_ranges)
52 TYPE(dbcsr_type) :: mat_global, mat_local
53 TYPE(mp_para_env_type), POINTER :: para_env
54 INTEGER :: num_pe_sub
55 INTEGER, DIMENSION(:, :), OPTIONAL :: atom_ranges
56
57 CHARACTER(LEN=*), PARAMETER :: routinen = 'global_matrix_to_local_matrix'
58
59 INTEGER :: block_counter, block_offset, block_size, col, col_from_buffer, col_offset, &
60 col_size, handle, handle1, i_block, i_entry, i_mepos, igroup, imep, imep_sub, msg_offset, &
61 nblkrows_total, ngroup, nmo, num_blocks, offset, row, row_from_buffer, row_offset, &
62 row_size, total_num_entries
63 INTEGER, ALLOCATABLE, DIMENSION(:) :: blk_counter, cols_to_alloc, entry_counter, &
64 num_entries_blocks_rec, num_entries_blocks_send, row_block_from_index, rows_to_alloc, &
65 sizes_rec, sizes_send
66 INTEGER, DIMENSION(:), POINTER :: row_blk_offset, row_blk_size
67 REAL(kind=dp), DIMENSION(:, :), POINTER :: data_block
68 TYPE(buffer_type), ALLOCATABLE, DIMENSION(:) :: buffer_rec, buffer_send
69 TYPE(dbcsr_iterator_type) :: iter
70
71 CALL timeset(routinen, handle)
72
73 CALL timeset("get_sizes", handle1)
74
75 NULLIFY (data_block)
76
77 ALLOCATE (num_entries_blocks_send(0:2*para_env%num_pe - 1))
78 num_entries_blocks_send(:) = 0
79
80 ALLOCATE (num_entries_blocks_rec(0:2*para_env%num_pe - 1))
81 num_entries_blocks_rec(:) = 0
82
83 ngroup = para_env%num_pe/num_pe_sub
84
85 CALL dbcsr_iterator_start(iter, mat_global)
86 DO WHILE (dbcsr_iterator_blocks_left(iter))
87
88 CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
89 row_size=row_size, col_size=col_size, &
90 row_offset=row_offset, col_offset=col_offset)
91
92 CALL dbcsr_get_stored_coordinates(mat_local, row, col, imep_sub)
93
94 DO igroup = 0, ngroup - 1
95
96 IF (PRESENT(atom_ranges)) THEN
97 IF (row < atom_ranges(1, igroup + 1) .OR. row > atom_ranges(2, igroup + 1)) cycle
98 END IF
99 imep = imep_sub + igroup*num_pe_sub
100
101 num_entries_blocks_send(2*imep) = num_entries_blocks_send(2*imep) + row_size*col_size
102 num_entries_blocks_send(2*imep + 1) = num_entries_blocks_send(2*imep + 1) + 1
103
104 END DO
105
106 END DO
107
108 CALL dbcsr_iterator_stop(iter)
109
110 CALL timestop(handle1)
111
112 CALL timeset("send_sizes_1", handle1)
113
114 total_num_entries = sum(num_entries_blocks_send)
115 CALL para_env%sum(total_num_entries)
116
117 CALL timestop(handle1)
118
119 CALL timeset("send_sizes_2", handle1)
120
121 IF (para_env%num_pe > 1) THEN
122 CALL para_env%alltoall(num_entries_blocks_send, num_entries_blocks_rec, 2)
123 ELSE
124 num_entries_blocks_rec(0:1) = num_entries_blocks_send(0:1)
125 END IF
126
127 CALL timestop(handle1)
128
129 CALL timeset("get_data", handle1)
130
131 ALLOCATE (buffer_rec(0:para_env%num_pe - 1))
132 ALLOCATE (buffer_send(0:para_env%num_pe - 1))
133
134 ! allocate data message and corresponding indices
135 DO imep = 0, para_env%num_pe - 1
136
137 ALLOCATE (buffer_rec(imep)%msg(num_entries_blocks_rec(2*imep)))
138 buffer_rec(imep)%msg = 0.0_dp
139
140 ALLOCATE (buffer_send(imep)%msg(num_entries_blocks_send(2*imep)))
141 buffer_send(imep)%msg = 0.0_dp
142
143 ALLOCATE (buffer_rec(imep)%indx(num_entries_blocks_rec(2*imep + 1), 3))
144 buffer_rec(imep)%indx = 0
145
146 ALLOCATE (buffer_send(imep)%indx(num_entries_blocks_send(2*imep + 1), 3))
147 buffer_send(imep)%indx = 0
148
149 END DO
150
151 ALLOCATE (entry_counter(0:para_env%num_pe - 1))
152 entry_counter(:) = 0
153
154 ALLOCATE (blk_counter(0:para_env%num_pe - 1))
155 blk_counter = 0
156
157 CALL dbcsr_iterator_start(iter, mat_global)
158 DO WHILE (dbcsr_iterator_blocks_left(iter))
159
160 CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
161 row_size=row_size, col_size=col_size, &
162 row_offset=row_offset, col_offset=col_offset)
163
164 CALL dbcsr_get_stored_coordinates(mat_local, row, col, imep_sub)
165
166 DO igroup = 0, ngroup - 1
167
168 IF (PRESENT(atom_ranges)) THEN
169 IF (row < atom_ranges(1, igroup + 1) .OR. row > atom_ranges(2, igroup + 1)) cycle
170 END IF
171
172 imep = imep_sub + igroup*num_pe_sub
173
174 msg_offset = entry_counter(imep)
175
176 block_size = row_size*col_size
177
178 buffer_send(imep)%msg(msg_offset + 1:msg_offset + block_size) = &
179 reshape(data_block(1:row_size, 1:col_size), (/block_size/))
180
181 entry_counter(imep) = entry_counter(imep) + block_size
182
183 blk_counter(imep) = blk_counter(imep) + 1
184
185 block_offset = blk_counter(imep)
186
187 buffer_send(imep)%indx(block_offset, 1) = row
188 buffer_send(imep)%indx(block_offset, 2) = col
189 buffer_send(imep)%indx(block_offset, 3) = msg_offset
190
191 END DO
192
193 END DO
194
195 CALL dbcsr_iterator_stop(iter)
196
197 CALL timestop(handle1)
198
199 CALL timeset("send_data", handle1)
200
201 ALLOCATE (sizes_rec(0:para_env%num_pe - 1))
202 ALLOCATE (sizes_send(0:para_env%num_pe - 1))
203
204 DO imep = 0, para_env%num_pe - 1
205 sizes_send(imep) = num_entries_blocks_send(2*imep)
206 sizes_rec(imep) = num_entries_blocks_rec(2*imep)
207 END DO
208
209 CALL communicate_buffer(para_env, sizes_rec, sizes_send, buffer_rec, buffer_send)
210
211 CALL timestop(handle1)
212
213 CALL timeset("row_block_from_index", handle1)
214
215 CALL dbcsr_get_info(mat_local, &
216 nblkrows_total=nblkrows_total, &
217 row_blk_offset=row_blk_offset, &
218 row_blk_size=row_blk_size)
219
220 ALLOCATE (row_block_from_index(nmo))
221 row_block_from_index = 0
222
223 DO i_entry = 1, nmo
224 DO i_block = 1, nblkrows_total
225
226 IF (i_entry >= row_blk_offset(i_block) .AND. &
227 i_entry <= row_blk_offset(i_block) + row_blk_size(i_block) - 1) THEN
228
229 row_block_from_index(i_entry) = i_block
230
231 END IF
232
233 END DO
234 END DO
235
236 CALL timestop(handle1)
237
238 CALL timeset("reserve_blocks", handle1)
239
240 num_blocks = 0
241
242 ! get the number of blocks, which have to be allocated
243 DO imep = 0, para_env%num_pe - 1
244 num_blocks = num_blocks + num_entries_blocks_rec(2*imep + 1)
245 END DO
246
247 ALLOCATE (rows_to_alloc(num_blocks))
248 rows_to_alloc = 0
249
250 ALLOCATE (cols_to_alloc(num_blocks))
251 cols_to_alloc = 0
252
253 block_counter = 0
254
255 DO i_mepos = 0, para_env%num_pe - 1
256
257 DO i_block = 1, num_entries_blocks_rec(2*i_mepos + 1)
258
259 block_counter = block_counter + 1
260
261 rows_to_alloc(block_counter) = buffer_rec(i_mepos)%indx(i_block, 1)
262 cols_to_alloc(block_counter) = buffer_rec(i_mepos)%indx(i_block, 2)
263
264 END DO
265
266 END DO
267
268 CALL dbcsr_set(mat_local, 0.0_dp)
269 CALL dbcsr_filter(mat_local, 1.0_dp)
270 CALL dbcsr_reserve_blocks(mat_local, rows=rows_to_alloc(:), cols=cols_to_alloc(:))
271 CALL dbcsr_finalize(mat_local)
272 CALL dbcsr_set(mat_local, 0.0_dp)
273
274 CALL timestop(handle1)
275
276 CALL timeset("fill_mat_local", handle1)
277
278 CALL dbcsr_iterator_start(iter, mat_local)
279
280 DO WHILE (dbcsr_iterator_blocks_left(iter))
281
282 CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
283 row_size=row_size, col_size=col_size)
284
285 DO imep = 0, para_env%num_pe - 1
286
287 DO i_block = 1, num_entries_blocks_rec(2*imep + 1)
288
289 row_from_buffer = buffer_rec(imep)%indx(i_block, 1)
290 col_from_buffer = buffer_rec(imep)%indx(i_block, 2)
291 offset = buffer_rec(imep)%indx(i_block, 3)
292
293 IF (row == row_from_buffer .AND. col == col_from_buffer) THEN
294
295 data_block(1:row_size, 1:col_size) = &
296 reshape(buffer_rec(imep)%msg(offset + 1:offset + row_size*col_size), &
297 (/row_size, col_size/))
298
299 END IF
300
301 END DO
302
303 END DO
304
305 END DO ! blocks
306
307 CALL dbcsr_iterator_stop(iter)
308
309 CALL timestop(handle1)
310
311 DO imep = 0, para_env%num_pe - 1
312 DEALLOCATE (buffer_rec(imep)%msg)
313 DEALLOCATE (buffer_rec(imep)%indx)
314 DEALLOCATE (buffer_send(imep)%msg)
315 DEALLOCATE (buffer_send(imep)%indx)
316 END DO
317
318 CALL timestop(handle)
319
320 END SUBROUTINE global_matrix_to_local_matrix
321
322! **************************************************************************************************
323!> \brief ...
324!> \param para_env ...
325!> \param num_entries_rec ...
326!> \param num_entries_send ...
327!> \param buffer_rec ...
328!> \param buffer_send ...
329!> \param do_indx ...
330!> \param do_msg ...
331! **************************************************************************************************
332 SUBROUTINE communicate_buffer(para_env, num_entries_rec, num_entries_send, &
333 buffer_rec, buffer_send, do_indx, do_msg)
334
335 TYPE(mp_para_env_type), POINTER :: para_env
336 INTEGER, ALLOCATABLE, DIMENSION(:) :: num_entries_rec, num_entries_send
337 TYPE(buffer_type), ALLOCATABLE, DIMENSION(:) :: buffer_rec, buffer_send
338 LOGICAL, OPTIONAL :: do_indx, do_msg
339
340 CHARACTER(LEN=*), PARAMETER :: routinen = 'communicate_buffer'
341
342 INTEGER :: handle, imep, rec_counter, send_counter
343 LOGICAL :: my_do_indx, my_do_msg
344 TYPE(mp_request_type), DIMENSION(:, :), POINTER :: req
345
346 CALL timeset(routinen, handle)
347
348 NULLIFY (req)
349 ALLOCATE (req(1:para_env%num_pe, 4))
350
351 my_do_indx = .true.
352 IF (PRESENT(do_indx)) my_do_indx = do_indx
353 my_do_msg = .true.
354 IF (PRESENT(do_msg)) my_do_msg = do_msg
355
356 IF (para_env%num_pe > 1) THEN
357
358 send_counter = 0
359 rec_counter = 0
360
361 DO imep = 0, para_env%num_pe - 1
362 IF (num_entries_rec(imep) > 0) THEN
363 rec_counter = rec_counter + 1
364 IF (my_do_indx) THEN
365 CALL para_env%irecv(buffer_rec(imep)%indx, imep, req(rec_counter, 3), tag=4)
366 END IF
367 IF (my_do_msg) THEN
368 CALL para_env%irecv(buffer_rec(imep)%msg, imep, req(rec_counter, 4), tag=7)
369 END IF
370 END IF
371 END DO
372
373 DO imep = 0, para_env%num_pe - 1
374 IF (num_entries_send(imep) > 0) THEN
375 send_counter = send_counter + 1
376 IF (my_do_indx) THEN
377 CALL para_env%isend(buffer_send(imep)%indx, imep, req(send_counter, 1), tag=4)
378 END IF
379 IF (my_do_msg) THEN
380 CALL para_env%isend(buffer_send(imep)%msg, imep, req(send_counter, 2), tag=7)
381 END IF
382 END IF
383 END DO
384
385 IF (my_do_indx) THEN
386 CALL mp_waitall(req(1:send_counter, 1))
387 CALL mp_waitall(req(1:rec_counter, 3))
388 END IF
389
390 IF (my_do_msg) THEN
391 CALL mp_waitall(req(1:send_counter, 2))
392 CALL mp_waitall(req(1:rec_counter, 4))
393 END IF
394
395 ELSE
396
397 buffer_rec(0)%indx = buffer_send(0)%indx
398 buffer_rec(0)%msg = buffer_send(0)%msg
399
400 END IF
401
402 DEALLOCATE (req)
403
404 CALL timestop(handle)
405
406 END SUBROUTINE communicate_buffer
407
408! **************************************************************************************************
409!> \brief ...
410!> \param mat_local ...
411!> \param mat_global ...
412!> \param para_env ...
413! **************************************************************************************************
414 SUBROUTINE local_matrix_to_global_matrix(mat_local, mat_global, para_env)
415
416 TYPE(dbcsr_type) :: mat_local, mat_global
417 TYPE(mp_para_env_type), POINTER :: para_env
418
419 CHARACTER(LEN=*), PARAMETER :: routinen = 'local_matrix_to_global_matrix'
420
421 INTEGER :: block_size, c, col, col_size, handle, &
422 handle1, i_block, imep, o, offset, r, &
423 rec_counter, row, row_size, &
424 send_counter
425 INTEGER, ALLOCATABLE, DIMENSION(:) :: block_counter, entry_counter, num_blocks_rec, &
426 num_blocks_send, num_entries_rec, num_entries_send, sizes_rec, sizes_send
427 REAL(kind=dp), DIMENSION(:, :), POINTER :: data_block
428 TYPE(buffer_type), ALLOCATABLE, DIMENSION(:) :: buffer_rec, buffer_send
429 TYPE(dbcsr_iterator_type) :: iter
430 TYPE(dbcsr_type) :: mat_global_copy
431 TYPE(mp_request_type), DIMENSION(:, :), POINTER :: req
432
433 CALL timeset(routinen, handle)
434
435 CALL timeset("get_coord", handle1)
436
437 CALL dbcsr_create(mat_global_copy, template=mat_global)
438 CALL dbcsr_reserve_all_blocks(mat_global_copy)
439
440 CALL dbcsr_set(mat_global, 0.0_dp)
441 CALL dbcsr_set(mat_global_copy, 0.0_dp)
442
443 ALLOCATE (buffer_rec(0:para_env%num_pe - 1))
444 ALLOCATE (buffer_send(0:para_env%num_pe - 1))
445
446 ALLOCATE (num_entries_rec(0:para_env%num_pe - 1))
447 ALLOCATE (num_blocks_rec(0:para_env%num_pe - 1))
448 ALLOCATE (num_entries_send(0:para_env%num_pe - 1))
449 ALLOCATE (num_blocks_send(0:para_env%num_pe - 1))
450 num_entries_rec = 0
451 num_blocks_rec = 0
452 num_entries_send = 0
453 num_blocks_send = 0
454
455 CALL dbcsr_iterator_start(iter, mat_local)
456 DO WHILE (dbcsr_iterator_blocks_left(iter))
457
458 CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
459 row_size=row_size, col_size=col_size)
460
461 CALL dbcsr_get_stored_coordinates(mat_global, row, col, imep)
462
463 num_entries_send(imep) = num_entries_send(imep) + row_size*col_size
464 num_blocks_send(imep) = num_blocks_send(imep) + 1
465
466 END DO
467
468 CALL dbcsr_iterator_stop(iter)
469
470 CALL timestop(handle1)
471
472 CALL timeset("comm_size", handle1)
473
474 IF (para_env%num_pe > 1) THEN
475
476 ALLOCATE (sizes_rec(0:2*para_env%num_pe - 1))
477 ALLOCATE (sizes_send(0:2*para_env%num_pe - 1))
478
479 DO imep = 0, para_env%num_pe - 1
480
481 sizes_send(2*imep) = num_entries_send(imep)
482 sizes_send(2*imep + 1) = num_blocks_send(imep)
483
484 END DO
485
486 CALL para_env%alltoall(sizes_send, sizes_rec, 2)
487
488 DO imep = 0, para_env%num_pe - 1
489 num_entries_rec(imep) = sizes_rec(2*imep)
490 num_blocks_rec(imep) = sizes_rec(2*imep + 1)
491 END DO
492
493 DEALLOCATE (sizes_rec, sizes_send)
494
495 ELSE
496
497 num_entries_rec(0) = num_entries_send(0)
498 num_blocks_rec(0) = num_blocks_send(0)
499
500 END IF
501
502 CALL timestop(handle1)
503
504 CALL timeset("fill_buffer", handle1)
505
506 ! allocate data message and corresponding indices
507 DO imep = 0, para_env%num_pe - 1
508
509 ALLOCATE (buffer_rec(imep)%msg(num_entries_rec(imep)))
510 buffer_rec(imep)%msg = 0.0_dp
511
512 ALLOCATE (buffer_send(imep)%msg(num_entries_send(imep)))
513 buffer_send(imep)%msg = 0.0_dp
514
515 ALLOCATE (buffer_rec(imep)%indx(num_blocks_rec(imep), 5))
516 buffer_rec(imep)%indx = 0
517
518 ALLOCATE (buffer_send(imep)%indx(num_blocks_send(imep), 5))
519 buffer_send(imep)%indx = 0
520
521 END DO
522
523 ALLOCATE (block_counter(0:para_env%num_pe - 1))
524 block_counter(:) = 0
525
526 ALLOCATE (entry_counter(0:para_env%num_pe - 1))
527 entry_counter(:) = 0
528
529 ! fill buffer_send
530 CALL dbcsr_iterator_start(iter, mat_local)
531 DO WHILE (dbcsr_iterator_blocks_left(iter))
532
533 CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
534 row_size=row_size, col_size=col_size)
535
536 CALL dbcsr_get_stored_coordinates(mat_global, row, col, imep)
537
538 block_size = row_size*col_size
539
540 offset = entry_counter(imep)
541
542 buffer_send(imep)%msg(offset + 1:offset + block_size) = &
543 reshape(data_block(1:row_size, 1:col_size), (/block_size/))
544
545 i_block = block_counter(imep) + 1
546
547 buffer_send(imep)%indx(i_block, 1) = row
548 buffer_send(imep)%indx(i_block, 2) = col
549 buffer_send(imep)%indx(i_block, 3) = offset
550
551 entry_counter(imep) = entry_counter(imep) + block_size
552
553 block_counter(imep) = block_counter(imep) + 1
554
555 END DO
556
557 CALL dbcsr_iterator_stop(iter)
558
559 CALL timestop(handle1)
560
561 CALL timeset("comm_data", handle1)
562
563 NULLIFY (req)
564 ALLOCATE (req(1:para_env%num_pe, 4))
565
566 IF (para_env%num_pe > 1) THEN
567
568 send_counter = 0
569 rec_counter = 0
570
571 DO imep = 0, para_env%num_pe - 1
572 IF (num_entries_rec(imep) > 0) THEN
573 rec_counter = rec_counter + 1
574 CALL para_env%irecv(buffer_rec(imep)%indx, imep, req(rec_counter, 3), tag=4)
575 END IF
576 IF (num_entries_rec(imep) > 0) THEN
577 CALL para_env%irecv(buffer_rec(imep)%msg, imep, req(rec_counter, 4), tag=7)
578 END IF
579 END DO
580
581 DO imep = 0, para_env%num_pe - 1
582 IF (num_entries_send(imep) > 0) THEN
583 send_counter = send_counter + 1
584 CALL para_env%isend(buffer_send(imep)%indx, imep, req(send_counter, 1), tag=4)
585 END IF
586 IF (num_entries_send(imep) > 0) THEN
587 CALL para_env%isend(buffer_send(imep)%msg, imep, req(send_counter, 2), tag=7)
588 END IF
589 END DO
590
591 CALL mp_waitall(req(1:send_counter, 1:2))
592 CALL mp_waitall(req(1:rec_counter, 3:4))
593
594 ELSE
595
596 buffer_rec(0)%indx = buffer_send(0)%indx
597 buffer_rec(0)%msg = buffer_send(0)%msg
598
599 END IF
600
601 CALL timestop(handle1)
602
603 CALL timeset("set_blocks", handle1)
604
605 ! fill mat_global_copy
606 CALL dbcsr_iterator_start(iter, mat_global_copy)
607 DO WHILE (dbcsr_iterator_blocks_left(iter))
608
609 CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
610 row_size=row_size, col_size=col_size)
611
612 DO imep = 0, para_env%num_pe - 1
613
614 DO i_block = 1, num_blocks_rec(imep)
615
616 IF (row == buffer_rec(imep)%indx(i_block, 1) .AND. &
617 col == buffer_rec(imep)%indx(i_block, 2)) THEN
618
619 offset = buffer_rec(imep)%indx(i_block, 3)
620
621 r = row_size
622 c = col_size
623 o = offset
624
625 data_block(1:r, 1:c) = data_block(1:r, 1:c) + &
626 reshape(buffer_rec(imep)%msg(o + 1:o + r*c), (/r, c/))
627
628 END IF
629
630 END DO
631
632 END DO
633
634 END DO
635
636 CALL dbcsr_iterator_stop(iter)
637
638 CALL dbcsr_copy(mat_global, mat_global_copy)
639
640 CALL dbcsr_release(mat_global_copy)
641
642 ! remove the blocks which are exactly zero from mat_global
643 CALL dbcsr_filter(mat_global, 1.0e-30_dp)
644
645 DO imep = 0, para_env%num_pe - 1
646 DEALLOCATE (buffer_rec(imep)%msg)
647 DEALLOCATE (buffer_send(imep)%msg)
648 DEALLOCATE (buffer_rec(imep)%indx)
649 DEALLOCATE (buffer_send(imep)%indx)
650 END DO
651
652 DEALLOCATE (buffer_rec, buffer_send)
653
654 DEALLOCATE (block_counter, entry_counter)
655
656 DEALLOCATE (req)
657
658 CALL dbcsr_set(mat_local, 0.0_dp)
659 CALL dbcsr_filter(mat_local, 1.0_dp)
660
661 CALL timestop(handle1)
662
663 CALL timestop(handle)
664
665 END SUBROUTINE local_matrix_to_global_matrix
666
667END MODULE gw_communication
subroutine, public global_matrix_to_local_matrix(mat_global, mat_local, para_env, num_pe_sub, atom_ranges)
...
subroutine, public local_matrix_to_global_matrix(mat_local, mat_global, para_env)
...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
stores all the informations relevant to an mpi environment