20 dbcsr_type_no_symmetry
41#include "./base/base_uses.f90"
52 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'ri_rs_matrices'
70 para_env, eps_filter, msg_elem_limit, unit_nr, periodic_images)
73 TYPE(
dbcsr_type),
INTENT(IN) :: matrix_template
75 REAL(kind=
dp),
INTENT(IN) :: eps_filter
76 INTEGER(KIND=int_8),
INTENT(IN) :: msg_elem_limit
77 INTEGER,
INTENT(IN) :: unit_nr
78 LOGICAL,
INTENT(IN) :: periodic_images
80 CHARACTER(LEN=*),
PARAMETER :: routinen =
'atomic_basis_at_grid_point'
81 INTEGER,
PARAMETER :: grid_panel_size = 4096
83 INTEGER :: blocks_per_panel, bs_eff, c_size, first_block, handle, i, i_blk, ia, iatom, &
84 ikind, last_block, n_grid, natom, npcol, nprow, num_grid_chunks, panel_size, panel_start, &
85 r_end, r_start, remaining, row_first, row_last, run, safe_max
86 INTEGER,
ALLOCATABLE :: blk_row_start(:)
87 INTEGER,
POINTER :: c_blk_sizes(:), col_dist(:), &
88 r_blk_sizes(:), row_dist(:)
89 REAL(kind=
dp) :: cutoff_squared
90 REAL(kind=
dp),
ALLOCATABLE :: atom_col_buffer(:, :)
94 CALL timeset(routinen, handle)
95 cpassert(
ASSOCIATED(ri_rs%cell))
96 cpassert(
ASSOCIATED(para_env))
97 cpassert(
ASSOCIATED(ri_rs%particle_set))
98 CALL dbcsr_get_info(matrix_template, distribution=template_dist, col_blk_size=c_blk_sizes)
99 natom =
SIZE(c_blk_sizes)
100 n_grid =
SIZE(ri_rs%grid_points, 2)
101 cpassert(
SIZE(ri_rs%particle_set) == natom)
102 cpassert(n_grid == ri_rs%n_grid_points)
106 IF (.NOT. periodic_images)
THEN
107 safe_max = int(msg_elem_limit*max(min(nprow, npcol), 1)/n_grid/2)
108 bs_eff = max(1, min(bs_eff, max(1, safe_max)))
110 IF (periodic_images)
THEN
111 num_grid_chunks = n_grid/bs_eff
112 IF (mod(n_grid, bs_eff) /= 0) num_grid_chunks = num_grid_chunks + 1
116 run = ri_rs%grid_atom_boundaries(ia + 1) - ri_rs%grid_atom_boundaries(ia)
117 IF (run > 0) num_grid_chunks = num_grid_chunks + (run + bs_eff - 1)/bs_eff
120 ALLOCATE (r_blk_sizes(num_grid_chunks), blk_row_start(num_grid_chunks))
123 DO ia = 1, merge(1, natom, periodic_images)
124 IF (periodic_images)
THEN
127 remaining = ri_rs%grid_atom_boundaries(ia + 1) - ri_rs%grid_atom_boundaries(ia)
129 DO WHILE (remaining > 0)
131 r_blk_sizes(i_blk) = min(bs_eff, remaining)
132 blk_row_start(i_blk) = r_start
133 r_start = r_start + r_blk_sizes(i_blk)
134 remaining = remaining - r_blk_sizes(i_blk)
138 IF (.NOT. periodic_images)
THEN
139 IF (unit_nr > 0)
THEN
140 WRITE (unit_nr,
'(T2,A,T71,I12)')
'RI-RS grid row-blocks of ϕ_μ(r_l)', num_grid_chunks
141 WRITE (unit_nr,
'(T2,A,T69,I12)')
'RI-RS grid points per block (max)', bs_eff
143 IF (ri_rs%cutoff_radius_v_w > 0.0_dp .OR. ri_rs%cutoff_radius_w0 > 0.0_dp)
THEN
144 IF (
ALLOCATED(ri_rs%chunk_centroids))
DEALLOCATE (ri_rs%chunk_centroids)
145 ALLOCATE (ri_rs%chunk_centroids(3, num_grid_chunks))
146 DO i_blk = 1, num_grid_chunks
147 r_start = blk_row_start(i_blk)
148 r_end = r_start + r_blk_sizes(i_blk) - 1
150 ri_rs%chunk_centroids(i, i_blk) = &
151 sum(ri_rs%grid_points(i, r_start:r_end))/real(r_blk_sizes(i_blk),
dp)
157 ALLOCATE (row_dist(num_grid_chunks), col_dist(natom))
158 DO i = 1, num_grid_chunks
159 row_dist(i) = mod(i - 1, nprow)
162 col_dist(i) = mod(i - 1, npcol)
165 CALL dbcsr_create(ri_rs%mat_phi_mu_l, name=
'phi_val_sparse', dist=dist, &
166 matrix_type=dbcsr_type_no_symmetry, row_blk_size=r_blk_sizes, col_blk_size=c_blk_sizes)
168 blocks_per_panel = max(1, grid_panel_size/maxval(r_blk_sizes))
169 DO iatom = para_env%mepos + 1, natom, para_env%num_pe
170 c_size = c_blk_sizes(iatom)
171 ALLOCATE (atom_col_buffer(min(n_grid, blocks_per_panel*maxval(r_blk_sizes)), c_size))
172 cutoff_squared = ri_rs%radius_ao_per_atom(iatom)**2
173 IF (.NOT. periodic_images .AND. ri_rs%cutoff_radius_ri_ao > 0.0_dp)
THEN
174 cutoff_squared = ri_rs%cutoff_radius_ri_ao**2
176 ikind = ri_rs%particle_set(iatom)%atomic_kind%kind_number
177 ao_basis => basis_set_ao(ikind)%gto_basis_set
178 DO first_block = 1, num_grid_chunks, blocks_per_panel
179 last_block = min(first_block + blocks_per_panel - 1, num_grid_chunks)
180 panel_start = blk_row_start(first_block)
181 panel_size = blk_row_start(last_block) + r_blk_sizes(last_block) - panel_start
182 atom_col_buffer(:panel_size, :) = 0.0_dp
184 ri_rs%grid_points(:, panel_start:panel_start + panel_size - 1), &
185 ao_basis, ri_rs%particle_set(iatom)%r, ri_rs%cell, &
186 cutoff_squared=cutoff_squared, periodic_images=periodic_images)
187 DO i_blk = first_block, last_block
188 row_first = blk_row_start(i_blk) - panel_start + 1
189 row_last = row_first + r_blk_sizes(i_blk) - 1
190 IF (maxval(abs(atom_col_buffer(row_first:row_last, :))) > eps_filter)
THEN
192 block=atom_col_buffer(row_first:row_last, :))
196 DEALLOCATE (atom_col_buffer)
199 DEALLOCATE (r_blk_sizes, row_dist, col_dist)
201 CALL timestop(handle)
214 TYPE(
dbcsr_type),
INTENT(IN) :: matrix_template
215 CHARACTER(LEN=*),
INTENT(IN) :: dim_type
217 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: blk_sizes, mapped_dist
219 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_square_topology'
221 INTEGER :: handle, i, np, npcols, nprows
222 INTEGER,
DIMENSION(:),
POINTER :: col_blk, col_dist, row_blk, row_dist
225 CALL timeset(routinen, handle)
227 CALL dbcsr_get_info(matrix_template, distribution=dist_template, &
228 row_blk_size=row_blk, col_blk_size=col_blk)
230 nprows=nprows, npcols=npcols)
232 IF (trim(dim_type) ==
'ROW')
THEN
236 ALLOCATE (mapped_dist(
SIZE(blk_sizes)))
237 DO i = 1,
SIZE(blk_sizes)
238 mapped_dist(i) = mod(i - 1, np)
241 row_dist=row_dist, col_dist=mapped_dist)
243 ELSE IF (trim(dim_type) ==
'COL')
THEN
247 ALLOCATE (mapped_dist(
SIZE(blk_sizes)))
248 DO i = 1,
SIZE(blk_sizes)
249 mapped_dist(i) = mod(i - 1, np)
252 row_dist=mapped_dist, col_dist=col_dist)
255 CALL timestop(handle)
272 INTEGER,
DIMENSION(:),
INTENT(INOUT),
OPTIONAL, &
273 POINTER :: mapped_dist
274 TYPE(
dbcsr_type),
INTENT(INOUT),
OPTIONAL :: m1, m2, m3, m4
276 CHARACTER(LEN=*),
PARAMETER :: routinen =
'release_dbcsr_topology_and_matrices'
280 CALL timeset(routinen, handle)
283 IF (
PRESENT(mapped_dist))
THEN
284 IF (
ASSOCIATED(mapped_dist))
THEN
285 DEALLOCATE (mapped_dist)
286 NULLIFY (mapped_dist)
294 CALL timestop(handle)
307 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: centers
308 REAL(kind=
dp),
INTENT(IN) :: radius
310 CHARACTER(LEN=*),
PARAMETER :: routinen =
'reserve_blocks_within_radius'
312 INTEGER :: handle, i, j, my_pcol, my_prow, &
314 INTEGER,
DIMENSION(:),
POINTER :: col_blk, col_dist, row_blk, row_dist
315 REAL(kind=
dp) :: radius2
316 REAL(kind=
dp),
ALLOCATABLE :: zero_blk(:, :)
319 CALL timeset(routinen, handle)
321 CALL dbcsr_get_info(matrix, nblkrows_total=nblkrows, nblkcols_total=nblkcols, &
322 row_blk_size=row_blk, col_blk_size=col_blk, distribution=dist)
324 myprow=my_prow, mypcol=my_pcol)
325 cpassert(nblkrows ==
SIZE(centers, 2))
326 cpassert(nblkcols ==
SIZE(centers, 2))
329 ALLOCATE (zero_blk(maxval(row_blk(1:nblkrows)), maxval(col_blk(1:nblkcols))))
330 zero_blk(:, :) = 0.0_dp
333 IF (row_dist(i) /= my_prow) cycle
335 IF (col_dist(j) /= my_pcol) cycle
336 IF (dot_product(centers(:, i) - centers(:, j), centers(:, i) - centers(:, j)) <= radius2)
THEN
337 CALL dbcsr_put_block(matrix, i, j, zero_blk(1:row_blk(i), 1:col_blk(j)))
343 DEALLOCATE (zero_blk)
344 CALL timestop(handle)
360 CHARACTER(LEN=*),
INTENT(IN) :: label
362 INTEGER,
INTENT(IN) :: unit_nr
363 INTEGER(KIND=int_8),
INTENT(IN) :: msg_elem_limit
364 CHARACTER(LEN=*),
INTENT(IN),
OPTIONAL :: suffix
366 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_matrix_occupation'
368 CHARACTER(LEN=32) :: output_format
369 CHARACTER(LEN=max_line_length) :: msg, output_label
370 INTEGER :: handle, i, unicode_shift
371 REAL(kind=
dp) :: frac_2p31, max_loc, occ
373 CALL timeset(routinen, handle)
377 CALL para_env%max(max_loc)
379 IF (unit_nr > 0)
THEN
380 frac_2p31 = max_loc/real(msg_elem_limit,
dp)
381 output_label =
'Percentage of non-zero matrix elements in '//trim(label)
382 IF (
PRESENT(suffix)) output_label = trim(output_label)//trim(suffix)
386 DO i = 1, len_trim(output_label)
387 IF (iand(iachar(output_label(i:i)), 192) == 128) unicode_shift = unicode_shift + 1
389 WRITE (output_format,
'(A,I0,A)')
'(T2,A,T', 72 + unicode_shift,
',F7.2,A)'
390 WRITE (unit_nr, output_format) trim(output_label), occ*100.0_dp,
' %'
391 IF (frac_2p31 > 0.5_dp)
THEN
392 WRITE (msg,
'(3A,F0.2,A)') &
393 "The largest per-rank message of ", trim(label),
" reaches ", frac_2p31, &
394 " of the 32-bit limit that DBCSR uses for its message length. Beyond it the "// &
395 "length overflows and multiply_cannon fails. Reduce the per-rank block size, "// &
396 "for instance with more MPI ranks."
402 CALL timestop(handle)
417 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: centroids
418 INTEGER,
INTENT(IN) :: blk0, blk1
419 REAL(kind=
dp),
INTENT(IN) :: cutoff
420 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: used
422 CHARACTER(LEN=*),
PARAMETER :: routinen =
'mask_grid_blocks_near_panel'
424 INTEGER :: c, handle, k
425 REAL(kind=
dp) :: cutoff2, d2, dx
426 REAL(kind=
dp),
DIMENSION(3) :: hi, lo
428 CALL timeset(routinen, handle)
431 lo(:) = minval(centroids(:, blk0:blk1), dim=2)
432 hi(:) = maxval(centroids(:, blk0:blk1), dim=2)
434 ALLOCATE (used(
SIZE(centroids, 2)))
435 DO c = 1,
SIZE(centroids, 2)
438 dx = max(0.0_dp, lo(k) - centroids(k, c), centroids(k, c) - hi(k))
441 used(c) = (d2 <= cutoff2)
444 CALL timestop(handle)
462 INTEGER,
DIMENSION(:),
INTENT(IN) :: r_blk_sizes
463 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: centroids
464 LOGICAL,
DIMENSION(:),
INTENT(IN) :: used
465 INTEGER,
INTENT(IN) :: blk0, blk1
466 REAL(kind=
dp),
INTENT(IN) :: cutoff
467 INTEGER(KIND=int_8),
INTENT(OUT) :: nze_tmpl
469 CHARACTER(LEN=*),
PARAMETER :: routinen =
'panel_template_elems'
471 INTEGER :: c, handle, ib, n_used
472 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: used_idx
473 REAL(kind=
dp) :: cutoff2
475 CALL timeset(routinen, handle)
479 ALLOCATE (used_idx(n_used))
494 IF (sum((centroids(:, ib) - centroids(:, used_idx(c)))**2) <= cutoff2)
THEN
495 nze_tmpl = nze_tmpl + int(r_blk_sizes(ib),
int_8)*int(r_blk_sizes(used_idx(c)),
int_8)
501 CALL timestop(handle)
523 INTEGER(KIND=int_8),
INTENT(IN) :: nze_tmpl
524 INTEGER,
INTENT(IN) :: pan_rows, width, n_grid_total, n_ri, &
526 REAL(kind=
dp),
INTENT(OUT) :: mem_gb
528 REAL(kind=
dp) :: f_near
530 f_near = real(width,
dp)/real(max(n_grid_total, 1),
dp)
531 mem_gb = (3.0_dp*real(nze_tmpl,
dp) + &
532 REAL(pan_rows,
dp)*f_near*(2.0_dp*
REAL(n_RI, dp) +
REAL(n_ao,
dp)))* &
533 8.0_dp/
REAL(MAX(n_procs, 1),
dp)*1.0e-9_dp
554 SUBROUTINE plan_grid_panels(msg_elem_limit, r_blk_sizes, min_dim, pan_first, pan_last, &
555 n_RI, n_ao, n_procs, mem_budget_GB, centroids, cutoff)
557 INTEGER(KIND=int_8),
INTENT(IN) :: msg_elem_limit
558 INTEGER,
DIMENSION(:),
INTENT(IN) :: r_blk_sizes
559 INTEGER,
INTENT(IN) :: min_dim
560 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: pan_first, pan_last
561 INTEGER,
INTENT(IN) :: n_ri, n_ao, n_procs
562 REAL(kind=
dp),
INTENT(IN) :: mem_budget_gb
563 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
564 OPTIONAL :: centroids
565 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: cutoff
567 CHARACTER(LEN=*),
PARAMETER :: routinen =
'plan_grid_panels'
569 INTEGER :: blk0, blk1, handle, ib, n_grid_blocks, &
570 n_grid_total, n_panels, panel_size, &
571 rows_acc,
TARGET, width
572 INTEGER(KIND=int_8) :: msg, msg_limit, nze_tmpl, side
573 INTEGER,
ALLOCATABLE :: tmp_first(:), tmp_last(:)
574 LOGICAL :: fits, use_cutoff, warned_memory, &
576 LOGICAL,
ALLOCATABLE :: used(:)
577 REAL(kind=
dp) :: f_near, mem_gb
579 CALL timeset(routinen, handle)
581 use_cutoff =
PRESENT(centroids) .AND.
PRESENT(cutoff)
582 IF (use_cutoff) use_cutoff = cutoff > 0.0_dp
583 msg_limit = msg_elem_limit/4
584 warned_memory = .false.
585 warned_message = .false.
586 n_grid_blocks =
SIZE(r_blk_sizes)
587 n_grid_total = sum(r_blk_sizes)
588 panel_size = n_grid_total
589 IF (.NOT. use_cutoff)
THEN
591 panel_size = int(0.5_dp*real(msg_elem_limit,
dp)*real(min_dim,
dp)/real(n_grid_total,
dp))
592 panel_size = max(1, min(panel_size, n_grid_total))
594 ALLOCATE (tmp_first(n_grid_blocks), tmp_last(n_grid_blocks))
598 DO WHILE (blk0 <= n_grid_blocks)
602 DO ib = blk0, n_grid_blocks
603 rows_acc = rows_acc + r_blk_sizes(ib)
605 IF (rows_acc >=
TARGET)
EXIT
607 IF (.NOT. use_cutoff)
EXIT
609 width = sum(r_blk_sizes, mask=used)
611 f_near = real(width,
dp)/real(max(n_grid_total, 1),
dp)
612 side = int(real(rows_acc,
dp)*f_near*real(max(n_ri, n_ao),
dp),
int_8)
613 msg = max(nze_tmpl, side)/int(max(min_dim, 1),
int_8)
615 n_ri, n_ao, n_procs, mem_gb)
616 fits = msg <= msg_limit
617 IF (mem_budget_gb > 0.0_dp) fits = fits .AND. mem_gb <= mem_budget_gb
619 IF (blk1 == blk0)
THEN
620 IF (msg > msg_limit .AND. .NOT. warned_message)
THEN
621 cpwarn(
"A single RI-RS grid block exceeds the estimated panel message limit.")
622 warned_message = .true.
624 IF (mem_budget_gb > 0.0_dp .AND. mem_gb > mem_budget_gb .AND. .NOT. warned_memory)
THEN
625 cpwarn(
"A single RI-RS grid block exceeds the estimated panel memory budget.")
626 warned_memory = .true.
631 TARGET = max(1, min(
TARGET, rows_acc)/2)
633 n_panels = n_panels + 1
634 tmp_first(n_panels) = blk0
635 tmp_last(n_panels) = blk1
639 ALLOCATE (pan_first, source=tmp_first(:n_panels))
640 ALLOCATE (pan_last, source=tmp_last(:n_panels))
641 CALL timestop(handle)
643 END SUBROUTINE plan_grid_panels
658 SUBROUTINE build_geo_template_panel(L_pan, L_full, centroids, cutoff, blk0, A_template, col_map)
660 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: centroids
661 REAL(kind=
dp),
INTENT(IN) :: cutoff
662 INTEGER,
INTENT(IN) :: blk0
664 INTEGER,
DIMENSION(:),
INTENT(IN) :: col_map
666 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_geo_template_panel'
668 INTEGER :: c, cg, cs, handle, my_pcol, my_prow, &
669 n_grid_blks, n_pan_blks, npcols, &
671 INTEGER,
DIMENSION(:),
POINTER :: grid_blk_sizes, pan_blk_sizes
672 REAL(kind=
dp) :: cutoff2
673 REAL(kind=
dp),
ALLOCATABLE :: zero_blk(:, :)
676 CALL timeset(routinen, handle)
679 CALL dbcsr_get_info(l_pan, nblkrows_total=n_pan_blks, row_blk_size=pan_blk_sizes)
680 CALL dbcsr_get_info(l_full, nblkrows_total=n_grid_blks, row_blk_size=grid_blk_sizes)
684 CALL create_product_matrix(l_pan, l_full,
'T', a_template)
687 myprow=my_prow, mypcol=my_pcol)
689 ALLOCATE (zero_blk(maxval(pan_blk_sizes(1:n_pan_blks)), &
690 maxval(grid_blk_sizes(1:n_grid_blks))))
691 zero_blk(:, :) = 0.0_dp
694 IF (mod(r - 1, nprows) /= my_prow) cycle
695 rs = pan_blk_sizes(r)
696 DO c = 1, n_grid_blks
697 IF (mod(c - 1, npcols) /= my_pcol) cycle
699 IF ((centroids(1, blk0 + r - 1) - centroids(1, cg))**2 + &
700 (centroids(2, blk0 + r - 1) - centroids(2, cg))**2 + &
701 (centroids(3, blk0 + r - 1) - centroids(3, cg))**2 <= cutoff2)
THEN
702 cs = grid_blk_sizes(c)
709 DEALLOCATE (zero_blk)
710 CALL timestop(handle)
712 END SUBROUTINE build_geo_template_panel
724 SUBROUTINE extract_grid_panel(mat_full, blk0, blk1, mat_panel)
727 INTEGER,
INTENT(IN) :: blk0, blk1
730 CHARACTER(LEN=*),
PARAMETER :: routinen =
'extract_grid_panel'
732 INTEGER :: handle, ib, jb, npb
733 INTEGER,
DIMENSION(:),
POINTER :: col_blk_full, col_dist_full, &
734 row_blk_full, row_blk_pan, &
735 row_dist_full, row_dist_pan
736 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: blk
740 CALL timeset(routinen, handle)
743 row_blk_size=row_blk_full, col_blk_size=col_blk_full)
746 npb = blk1 - blk0 + 1
747 ALLOCATE (row_dist_pan(npb), row_blk_pan(npb))
748 row_dist_pan(:) = row_dist_full(blk0:blk1)
749 row_blk_pan(:) = row_blk_full(blk0:blk1)
752 row_dist=row_dist_pan, col_dist=col_dist_full)
753 CALL dbcsr_create(mat_panel, name=
"grid_panel", dist=dist_pan, &
754 matrix_type=dbcsr_type_no_symmetry, &
755 row_blk_size=row_blk_pan, col_blk_size=col_blk_full)
760 IF (ib < blk0 .OR. ib > blk1) cycle
767 DEALLOCATE (row_dist_pan, row_blk_pan)
769 CALL timestop(handle)
771 END SUBROUTINE extract_grid_panel
781 SUBROUTINE collect_used_col_blocks(matrix, para_env, used)
785 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: used
787 CHARACTER(LEN=*),
PARAMETER :: routinen =
'collect_used_col_blocks'
789 INTEGER :: handle, ib, jb, nblkcols
790 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iused
791 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: blk
794 CALL timeset(routinen, handle)
797 ALLOCATE (iused(nblkcols))
807 CALL para_env%sum(iused)
809 ALLOCATE (used(nblkcols))
810 used(:) = (iused(:) > 0)
813 CALL timestop(handle)
815 END SUBROUTINE collect_used_col_blocks
828 SUBROUTINE extract_masked_blocks(mat_full, used, mat_out, compress_rows, blk_map)
831 LOGICAL,
DIMENSION(:),
INTENT(IN) :: used
833 LOGICAL,
INTENT(IN) :: compress_rows
834 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT), &
837 CHARACTER(LEN=*),
PARAMETER :: routinen =
'extract_masked_blocks'
839 INTEGER :: handle, ib, jb, n_blk, n_sub, r
840 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: inv_map
841 INTEGER,
DIMENSION(:),
POINTER :: blk_full, blk_sub, col_blk_full, &
842 col_dist_full, dist_full_1d, &
843 dist_sub_1d, row_blk_full, &
845 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: blk
849 CALL timeset(routinen, handle)
852 row_blk_size=row_blk_full, col_blk_size=col_blk_full)
855 IF (compress_rows)
THEN
856 blk_full => row_blk_full
857 dist_full_1d => row_dist_full
859 blk_full => col_blk_full
860 dist_full_1d => col_dist_full
862 n_blk =
SIZE(blk_full)
866 ALLOCATE (inv_map(n_blk), blk_sub(n_sub), dist_sub_1d(n_sub))
867 IF (
PRESENT(blk_map))
ALLOCATE (blk_map(n_sub))
874 blk_sub(r) = blk_full(ib)
875 dist_sub_1d(r) = dist_full_1d(ib)
876 IF (
PRESENT(blk_map)) blk_map(r) = ib
880 IF (compress_rows)
THEN
882 row_dist=dist_sub_1d, col_dist=col_dist_full)
883 CALL dbcsr_create(mat_out, name=
"row_subset", dist=dist_sub, &
884 matrix_type=dbcsr_type_no_symmetry, &
885 row_blk_size=blk_sub, col_blk_size=col_blk_full)
888 row_dist=row_dist_full, col_dist=dist_sub_1d)
889 CALL dbcsr_create(mat_out, name=
"col_subset", dist=dist_sub, &
890 matrix_type=dbcsr_type_no_symmetry, &
891 row_blk_size=row_blk_full, col_blk_size=blk_sub)
897 IF (compress_rows)
THEN
898 IF (inv_map(ib) > 0)
CALL dbcsr_put_block(mat_out, inv_map(ib), jb, blk)
900 IF (inv_map(jb) > 0)
CALL dbcsr_put_block(mat_out, ib, inv_map(jb), blk)
907 DEALLOCATE (inv_map, blk_sub, dist_sub_1d)
909 CALL timestop(handle)
911 END SUBROUTINE extract_masked_blocks
922 SUBROUTINE create_product_matrix(mat_left, mat_right, transb, mat_out)
924 TYPE(
dbcsr_type),
INTENT(IN) :: mat_left, mat_right
925 CHARACTER(LEN=1),
INTENT(IN) :: transb
928 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_product_matrix'
930 INTEGER :: handle, i, npcols, nprows
931 INTEGER,
DIMENSION(:),
POINTER :: col_blk_r, out_col_blk, out_col_dist, &
932 out_row_blk, out_row_dist, row_blk_l, &
936 CALL timeset(routinen, handle)
938 CALL dbcsr_get_info(mat_left, distribution=dist_l, row_blk_size=row_blk_l)
939 CALL dbcsr_get_info(mat_right, row_blk_size=row_blk_r, col_blk_size=col_blk_r)
945 out_row_blk => row_blk_l
946 IF (transb ==
'N')
THEN
947 out_col_blk => col_blk_r
949 out_col_blk => row_blk_r
952 ALLOCATE (out_row_dist(
SIZE(out_row_blk)), out_col_dist(
SIZE(out_col_blk)))
953 DO i = 1,
SIZE(out_row_blk)
954 out_row_dist(i) = mod(i - 1, nprows)
956 DO i = 1,
SIZE(out_col_blk)
957 out_col_dist(i) = mod(i - 1, npcols)
961 row_dist=out_row_dist, col_dist=out_col_dist)
962 CALL dbcsr_create(mat_out, name=
"panel_product", dist=dist_out, &
963 matrix_type=dbcsr_type_no_symmetry, &
964 row_blk_size=out_row_blk, col_blk_size=out_col_blk)
966 DEALLOCATE (out_row_dist, out_col_dist)
968 CALL timestop(handle)
970 END SUBROUTINE create_product_matrix
1007 pan_first, pan_last, lb_eq_la, lout_eq_la, zero_out, &
1008 centroids, cutoff, grid_occupation)
1010 TYPE(
dbcsr_type),
INTENT(INOUT),
TARGET :: l_a
1011 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(INOUT) :: m_a
1012 TYPE(
dbcsr_type),
INTENT(INOUT),
TARGET :: l_b
1014 TYPE(
dbcsr_type),
INTENT(INOUT),
TARGET :: l_out
1015 TYPE(
dbcsr_p_type),
DIMENSION(:),
INTENT(IN) :: mat_out
1016 REAL(kind=
dp),
INTENT(IN) :: scale, eps
1018 INTEGER,
DIMENSION(:),
INTENT(IN) :: pan_first, pan_last
1019 LOGICAL,
INTENT(IN) :: lb_eq_la, lout_eq_la, zero_out
1020 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
1021 OPTIONAL :: centroids
1022 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: cutoff
1023 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: grid_occupation
1025 CHARACTER(LEN=*),
PARAMETER :: routinen =
'contract_grid_panels'
1027 INTEGER :: blk0, blk1, handle, i_a, ipan, &
1028 n_grid_total, ncols_pan, nrows_pan
1029 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: gmap
1030 LOGICAL :: use_cutoff
1031 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: grid_used, useda, usedb
1032 TYPE(
dbcsr_type) :: a_pan(2), b_pan, lb_pan, lb_panc, &
1033 ma_sub, mb_sub, tmp2, tmpa, tmpb
1034 TYPE(
dbcsr_type),
POINTER :: panel_out, rb_a, rb_b, rb_out
1035 TYPE(
dbcsr_type),
TARGET :: la_near, la_pan, la_panc, lb_near, &
1038 CALL timeset(routinen, handle)
1040 cpassert(
SIZE(m_a) >= 1 .AND.
SIZE(m_a) <= 2)
1041 cpassert(
SIZE(mat_out) ==
SIZE(m_a))
1043 use_cutoff =
PRESENT(centroids) .AND.
PRESENT(cutoff)
1044 IF (use_cutoff) use_cutoff = cutoff > 0.0_dp
1045 IF (
PRESENT(grid_occupation)) grid_occupation = 0.0_dp
1050 DO i_a = 1,
SIZE(mat_out)
1051 CALL dbcsr_set(mat_out(i_a)%matrix, 0.0_dp)
1055 DO ipan = 1,
SIZE(pan_first)
1056 blk0 = pan_first(ipan)
1057 blk1 = pan_last(ipan)
1060 CALL extract_grid_panel(l_a, blk0, blk1, la_pan)
1061 CALL collect_used_col_blocks(la_pan, para_env, useda)
1062 IF (.NOT. lb_eq_la)
THEN
1063 CALL extract_grid_panel(l_b, blk0, blk1, lb_pan)
1064 CALL collect_used_col_blocks(lb_pan, para_env, usedb)
1066 IF (
ALLOCATED(usedb))
DEALLOCATE (usedb)
1067 ALLOCATE (usedb, source=useda)
1069 IF (.NOT. any(useda) .OR. .NOT. any(usedb))
THEN
1074 IF (lout_eq_la)
THEN
1077 CALL extract_grid_panel(l_out, blk0, blk1, lout_pan)
1078 panel_out => lout_pan
1080 CALL extract_masked_blocks(la_pan, useda, la_panc, compress_rows=.false.)
1086 IF (use_cutoff)
THEN
1088 CALL extract_masked_blocks(l_a, grid_used, la_near, compress_rows=.true., blk_map=gmap)
1089 IF (.NOT. lb_eq_la)
CALL extract_masked_blocks(l_b, grid_used, lb_near, compress_rows=.true.)
1090 IF (.NOT. lout_eq_la)
CALL extract_masked_blocks(l_out, grid_used, lout_near, compress_rows=.true.)
1097 ELSE IF (use_cutoff)
THEN
1102 IF (lout_eq_la)
THEN
1104 ELSE IF (use_cutoff)
THEN
1110 DO i_a = 1,
SIZE(m_a)
1115 CALL extract_masked_blocks(m_a(i_a), useda, ma_sub, compress_rows=.true.)
1116 CALL create_product_matrix(la_panc, ma_sub,
'N', tmpa)
1117 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, la_panc, ma_sub, 0.0_dp, tmpa, filter_eps=eps)
1119 IF (use_cutoff)
THEN
1120 CALL build_geo_template_panel(la_pan, la_near, centroids, cutoff, blk0, a_pan(i_a), &
1123 CALL create_product_matrix(tmpa, rb_a,
'T', a_pan(i_a))
1125 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpa, rb_a, 0.0_dp, a_pan(i_a), &
1126 filter_eps=eps, retain_sparsity=use_cutoff)
1134 IF (
PRESENT(grid_occupation) .AND. i_a == 1)
THEN
1135 CALL dbcsr_get_info(a_pan(i_a), nfullrows_total=nrows_pan, nfullcols_total=ncols_pan)
1137 REAL(ncols_pan,
dp)*
REAL(nrows_pan,
dp)/ &
1138 (
REAL(n_grid_total,
dp)*
REAL(n_grid_total,
dp))
1146 CALL extract_masked_blocks(m_b, useda, mb_sub, compress_rows=.true.)
1147 CALL create_product_matrix(la_panc, mb_sub,
'N', tmpb)
1148 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, la_panc, mb_sub, 0.0_dp, tmpb, filter_eps=eps)
1150 CALL extract_masked_blocks(lb_pan, usedb, lb_panc, compress_rows=.false.)
1151 CALL extract_masked_blocks(m_b, usedb, mb_sub, compress_rows=.true.)
1152 CALL create_product_matrix(lb_panc, mb_sub,
'N', tmpb)
1153 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, lb_panc, mb_sub, 0.0_dp, tmpb, filter_eps=eps)
1159 IF (
SIZE(m_a) == 2)
CALL dbcsr_add(b_pan, a_pan(2), 1.0_dp, 1.0_dp)
1163 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpb, rb_b, 0.0_dp, b_pan, &
1164 retain_sparsity=.true.)
1168 DO i_a = 1,
SIZE(m_a)
1171 CALL create_product_matrix(a_pan(i_a), rb_out,
'N', tmp2)
1172 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, a_pan(i_a), rb_out, 0.0_dp, tmp2, filter_eps=eps)
1176 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, panel_out, tmp2, 1.0_dp, mat_out(i_a)%matrix, filter_eps=eps)
1183 IF (use_cutoff)
THEN
1191 CALL timestop(handle)
1207 mat_Z_lP, matrix_V_aux)
1209 TYPE(
cp_fm_type),
INTENT(IN) :: metric_inverse
1210 TYPE(libint_potential_type),
INTENT(IN) :: trunc_coulomb
1213 TYPE(
dbcsr_type),
INTENT(OUT) :: matrix_v_aux
1215 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_ri_rs_bare_aux_interaction'
1218 INTEGER,
POINTER :: blk_aux(:), dist_row_aux(:)
1219 TYPE(
cp_fm_type),
ALLOCATABLE :: fm_vtr_gamma(:, :)
1222 CALL timeset(routinen, handle)
1223 IF (auto_ri%enabled)
THEN
1224 cpassert(auto_ri%ready)
1225 ALLOCATE (fm_vtr_gamma(1, 1))
1226 CALL cp_fm_create(fm_vtr_gamma(1, 1), metric_inverse%matrix_struct)
1227 CALL cp_fm_to_fm(auto_ri%V_pq, fm_vtr_gamma(1, 1))
1230 metric_inverse%matrix_struct%nrow_global, trunc_coulomb)
1234 CALL dbcsr_create(matrix_v_aux,
"V_aux", dist_aux_aux, dbcsr_type_no_symmetry, blk_aux, blk_aux)
1235 CALL copy_fm_to_dbcsr(fm_vtr_gamma(1, 1), matrix_v_aux, keep_sparsity=.false.)
1238 CALL timestop(handle)
1254 INTEGER(KIND=int_8),
INTENT(IN) :: msg_elem_limit
1255 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: pan_first, pan_last
1256 REAL(kind=
dp),
INTENT(IN) :: cutoff
1258 CHARACTER(LEN=*),
PARAMETER :: routinen =
'resolve_grid_panels'
1260 INTEGER :: handle, min_dim, n_ao, n_grid_total, &
1261 n_ri, npcols, nprows
1262 INTEGER,
DIMENSION(:),
POINTER :: r_blk_sizes
1263 LOGICAL :: use_cutoff
1264 REAL(kind=
dp) :: effective_cutoff, mem_avail_gb, &
1268 CALL timeset(routinen, handle)
1270 use_cutoff = cutoff > 0.0_dp .AND. &
1271 ALLOCATED(ri_rs%chunk_centroids)
1272 effective_cutoff = 0.0_dp
1273 IF (use_cutoff) effective_cutoff = cutoff
1274 IF (
ALLOCATED(ri_rs%pan_first))
THEN
1276 IF (ri_rs%panel_plan_cutoff == effective_cutoff)
THEN
1277 ALLOCATE (pan_first, source=ri_rs%pan_first)
1278 ALLOCATE (pan_last, source=ri_rs%pan_last)
1279 CALL timestop(handle)
1282 DEALLOCATE (ri_rs%pan_first, ri_rs%pan_last)
1289 CALL dbcsr_get_info(ri_rs%mat_phi_mu_l, nfullrows_total=n_grid_total, nfullcols_total=n_ao, &
1290 row_blk_size=r_blk_sizes, distribution=dist)
1292 min_dim = max(min(nprows, npcols), 1)
1296 mem_budget_gb = 0.0_dp
1297 IF (use_cutoff)
THEN
1299 mem_budget_gb = 0.5_dp*mem_avail_gb
1301 CALL plan_grid_panels(msg_elem_limit, r_blk_sizes, min_dim, pan_first, pan_last, &
1302 n_ri, n_ao, para_env%num_pe, mem_budget_gb, &
1303 centroids=ri_rs%chunk_centroids, cutoff=effective_cutoff)
1305 ALLOCATE (ri_rs%pan_first, source=pan_first)
1306 ALLOCATE (ri_rs%pan_last, source=pan_last)
1307 ri_rs%panel_plan_cutoff = effective_cutoff
1309 CALL timestop(handle)
subroutine, public dbcsr_distribution_release(dist)
...
integer function, public dbcsr_get_data_size(matrix)
...
subroutine, public dbcsr_distribution_new(dist, template, group, pgrid, row_dist, col_dist, reuse_arrays)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
real(kind=dp) function, public dbcsr_get_occupation(matrix)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_put_block(matrix, row, col, block, summation)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_distribution_get(dist, row_dist, col_dist, nrows, ncols, has_threads, group, mynode, numnodes, nprows, npcols, myprow, mypcol, pgrid, subgroups_defined, prow_group, pcol_group)
...
DBCSR operations in CP2K.
integer, save, public max_elements_per_block
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
represent a full matrix distributed on many processors
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
Input and persistent data for automatic RI basis optimization.
Common DBCSR matrix operations used by GW modules.
subroutine, public hadamard_product_inplace(matrix_a, matrix_b, factor)
Form A = factor * (A element-wise B) without changing A's block structure.
Full-matrix operations not provided by the CP2K FM packages.
Defines the basic variable types.
integer, parameter, public max_line_length
integer, parameter, public int_8
integer, parameter, public dp
2- and 3-center electron repulsion integral routines based on libint2 Currently available operators: ...
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Interface to the message passing library MPI.
subroutine, public mp_mem_avail_per_rank_gb(comm, mem_avail_gb)
Memory that is currently free on the node, per MPI rank of that node, in GB.
Framework for 2c-integrals for RI.
subroutine, public ri_2c_integral_mat(qs_env, fm_matrix_minv_l_gamma, fm_matrix_l_struct, dimen_ri, ri_metric, put_mat_ks_env, regularization_ri)
...
DBCSR collocation, layouts and panel contractions for real-space resolution of the identity.
subroutine, public release_dbcsr_topology_and_matrices(dist, mapped_dist, m1, m2, m3, m4)
Releases RI-RS topology mappings and temporary DBCSR matrices.
subroutine, public resolve_grid_panels(ri_rs, para_env, msg_elem_limit, pan_first, pan_last, cutoff)
Resolve and cache grid-panel boundaries for RI-RS streaming contractions.
subroutine, public panel_template_elems(r_blk_sizes, centroids, used, blk0, blk1, cutoff, nze_tmpl)
Exact allocated-element count of the geo template of panel [blk0, blk1]: the very same per-block-pair...
subroutine, public setup_square_topology(matrix_template, dim_type, square_dist, blk_sizes, mapped_dist)
Creates a square topology from a selected row or column layout.
subroutine, public print_matrix_occupation(matrix, label, para_env, unit_nr, msg_elem_limit, suffix)
Prints the percentage of non-zero elements in a distributed RI-RS matrix.
subroutine, public panel_mem_estimate_gb(nze_tmpl, pan_rows, width, n_grid_total, n_ri, n_ao, n_procs, mem_gb)
Per-rank peak memory (GB) of one panel step of the neighborhood-restricted contractions: up to three ...
subroutine, public mask_grid_blocks_near_panel(centroids, blk0, blk1, cutoff, used)
Marks the grid blocks whose centroid lies within cutoff of the bounding box of the panel [blk0,...
subroutine, public build_ri_rs_bare_aux_interaction(qs_env, metric_inverse, trunc_coulomb, auto_ri, mat_z_lp, matrix_v_aux)
Build the unfiltered auxiliary interaction M^-1 V^tr M^-1 in the Z-column layout. AUTO_RI uses its al...
subroutine, public reserve_blocks_within_radius(matrix, centers, radius)
Reserves grid blocks with block-centre distances within a fixed radius.
subroutine, public atomic_basis_at_grid_point(ri_rs, basis_set_ao, matrix_template, para_env, eps_filter, msg_elem_limit, unit_nr, periodic_images)
Builds the grid-by-AO collocation matrix with bounded dense evaluation panels. The molecular path use...
subroutine, public contract_grid_panels(l_a, m_a, l_b, m_b, l_out, mat_out, scale, eps, para_env, pan_first, pan_last, lb_eq_la, lout_eq_la, zero_out, centroids, cutoff, grid_occupation)
Projects two operators onto grid panels, takes their Hadamard product, and back-projects it: out += s...
Shared real-space resolution-of-identity grid and matrix data.
Geometry and AO evaluation for real-space resolution of the identity.
subroutine, public evaluate_ao_basis_on_points(phi, grid_points, basis, source_position, cell, dphi, cutoff_squared, periodic_images)
Evaluate one explicitly supplied contracted Gaussian basis on Cartesian points.
stores all the informations relevant to an mpi environment