49#include "base/base_uses.f90"
54 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_dbcsr_operations'
55 LOGICAL,
PARAMETER :: debug_mod = .false.
78 MODULE PROCEDURE allocate_dbcsr_matrix_set_1d
79 MODULE PROCEDURE allocate_dbcsr_matrix_set_2d
80 MODULE PROCEDURE allocate_dbcsr_matrix_set_3d
81 MODULE PROCEDURE allocate_dbcsr_matrix_set_4d
82 MODULE PROCEDURE allocate_dbcsr_matrix_set_5d
86 MODULE PROCEDURE deallocate_dbcsr_matrix_set_1d
87 MODULE PROCEDURE deallocate_dbcsr_matrix_set_2d
88 MODULE PROCEDURE deallocate_dbcsr_matrix_set_3d
89 MODULE PROCEDURE deallocate_dbcsr_matrix_set_4d
90 MODULE PROCEDURE deallocate_dbcsr_matrix_set_5d
113 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
115 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_fm_to_dbcsr'
118 LOGICAL :: my_keep_sparsity
121 CALL timeset(routinen, handle)
123 my_keep_sparsity = .false.
124 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
128 IF (my_keep_sparsity)
THEN
131 CALL dbcsr_copy(matrix, redist_mat, keep_sparsity=.true.)
139 CALL timestop(handle)
152 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_fm_to_dbcsr_bc'
154 INTEGER :: col, handle, ncol_block, ncol_global, &
155 nrow_block, nrow_global, row
156 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: first_col, first_row, last_col, last_row
157 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, row_blk_size
158 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
159 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: dbcsr_block, fm_block
163 CALL timeset(routinen, handle)
165 IF (fm%use_sp) cpabort(
"copy_fm_to_dbcsr_bc: single precision not supported")
168 pgrid => fm%matrix_struct%context%blacs2mpi
171 nrow_block = fm%matrix_struct%nrow_block
172 ncol_block = fm%matrix_struct%ncol_block
173 nrow_global = fm%matrix_struct%nrow_global
174 ncol_global = fm%matrix_struct%ncol_global
175 NULLIFY (col_blk_size, row_blk_size)
176 CALL dbcsr_create_dist_block_cyclic(bc_dist, &
177 nrows=nrow_global, ncolumns=ncol_global, &
178 nrow_block=nrow_block, ncol_block=ncol_block, &
179 group_handle=fm%matrix_struct%para_env%get_handle(), pgrid=pgrid, &
180 row_blk_sizes=row_blk_size, col_blk_sizes=col_blk_size)
184 dbcsr_type_no_symmetry, row_blk_size, col_blk_size, reuse_arrays=.true.)
190 CALL calculate_fm_block_ranges(bc_mat, first_row, last_row, first_col, last_col)
194 fm_block => fm%local_data
200 dbcsr_block(:, :) = fm_block(first_row(row):last_row(row), first_col(col):last_col(col))
205 CALL timestop(handle)
217 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_dbcsr_to_fm'
219 CHARACTER(len=default_string_length) :: name
220 INTEGER :: group_handle, handle, ncol_block, &
221 nfullcols_total, nfullrows_total, &
223 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, row_blk_size
224 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
228 CALL timeset(routinen, handle)
234 nfullrows_total=nfullrows_total, &
235 nfullcols_total=nfullcols_total)
237 cpassert(fm%matrix_struct%nrow_global == nfullrows_total)
238 cpassert(fm%matrix_struct%ncol_global == nfullcols_total)
241 nrow_block = fm%matrix_struct%nrow_block
242 ncol_block = fm%matrix_struct%ncol_block
245 NULLIFY (col_blk_size, row_blk_size)
247 CALL dbcsr_create_dist_block_cyclic(bc_dist, &
248 nrows=nfullrows_total, ncolumns=nfullcols_total, &
249 nrow_block=nrow_block, ncol_block=ncol_block, &
250 group_handle=group_handle, pgrid=pgrid, &
251 row_blk_sizes=row_blk_size, col_blk_sizes=col_blk_size)
253 CALL dbcsr_create(bc_mat,
"Block-cyclic"//name, bc_dist, &
254 dbcsr_type_no_symmetry, row_blk_size, col_blk_size, reuse_arrays=.true.)
257 CALL dbcsr_create(matrix_nosym, template=matrix, matrix_type=
"N")
266 CALL timestop(handle)
278 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_dbcsr_to_fm_bc'
280 INTEGER :: col, handle, row
281 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: first_col, first_row, last_col, last_row
282 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: dbcsr_block, fm_block
285 CALL timeset(routinen, handle)
287 IF (fm%use_sp) cpabort(
"copy_dbcsr_to_fm_bc: single precision not supported")
289 CALL calculate_fm_block_ranges(bc_mat, first_row, last_row, first_col, last_col)
292 fm_block => fm%local_data
293 fm_block = real(0.0, kind=
dp)
299 fm_block(first_row(row):last_row(row), first_col(col):last_col(col)) = dbcsr_block(:, :)
304 CALL timestop(handle)
316 SUBROUTINE calculate_fm_block_ranges(bc_mat, first_row, last_row, first_col, last_col)
318 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: first_row, last_row, first_col, last_col
320 INTEGER :: col, nblkcols_local, nblkcols_total, &
321 nblkrows_local, nblkrows_total, row
322 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: local_col_sizes, local_row_sizes
323 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, local_cols, local_rows, &
327 nblkrows_total=nblkrows_total, &
328 nblkcols_total=nblkcols_total, &
329 nblkrows_local=nblkrows_local, &
330 nblkcols_local=nblkcols_local, &
331 local_rows=local_rows, &
332 local_cols=local_cols, &
333 row_blk_size=row_blk_size, &
334 col_blk_size=col_blk_size)
337 ALLOCATE (local_row_sizes(nblkrows_total))
338 local_row_sizes(:) = 0
339 IF (nblkrows_local .GE. 1)
THEN
340 DO row = 1, nblkrows_local
341 local_row_sizes(local_rows(row)) = row_blk_size(local_rows(row))
344 ALLOCATE (first_row(nblkrows_total), last_row(nblkrows_total))
345 CALL dbcsr_convert_sizes_to_offsets(local_row_sizes, first_row, last_row)
346 DEALLOCATE (local_row_sizes)
349 ALLOCATE (local_col_sizes(nblkcols_total))
350 local_col_sizes(:) = 0
351 IF (nblkcols_local .GE. 1)
THEN
352 DO col = 1, nblkcols_local
353 local_col_sizes(local_cols(col)) = col_blk_size(local_cols(col))
356 ALLOCATE (first_col(nblkcols_total), last_col(nblkcols_total))
357 CALL dbcsr_convert_sizes_to_offsets(local_col_sizes, first_col, last_col)
358 DEALLOCATE (local_col_sizes)
360 END SUBROUTINE calculate_fm_block_ranges
374 ncol, source_start, target_start, para_env, blacs_env)
378 INTEGER,
INTENT(IN) :: ncol, source_start, target_start
382 INTEGER :: nfullcols_total, nfullrows_total
387 CALL dbcsr_get_info(matrix_a, nfullrows_total=nfullrows_total, nfullcols_total=nfullcols_total)
389 ncol_global=nfullcols_total, para_env=para_env)
390 CALL cp_fm_create(fm_matrix_a, fm_struct, name=
"fm_matrix_a")
393 CALL dbcsr_get_info(matrix_b, nfullrows_total=nfullrows_total, nfullcols_total=nfullcols_total)
395 ncol_global=nfullcols_total, para_env=para_env)
396 CALL cp_fm_create(fm_matrix_b, fm_struct, name=
"fm_matrix_b")
402 CALL cp_fm_to_fm(fm_matrix_a, fm_matrix_b, ncol, source_start, target_start)
422 INTEGER,
DIMENSION(:),
POINTER :: col_dist, row_dist
423 INTEGER,
DIMENSION(:, :),
POINTER :: col_dist_data, pgrid, row_dist_data
430 row_distribution=row_dist_data, &
431 col_distribution=col_dist_data, &
433 CALL blacs_env%get(para_env=para_env, blacs2mpi=pgrid)
436 row_dist => row_dist_data(:, 1)
437 col_dist => col_dist_data(:, 1)
442 group=para_env%get_handle(), pgrid=pgrid, &
460 REAL(
dp),
DIMENSION(:, :),
INTENT(IN) :: vec_b
461 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT) :: vec_c
462 INTEGER,
INTENT(in),
OPTIONAL :: ncol
463 REAL(
dp),
INTENT(IN),
OPTIONAL :: alpha
465 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_multiply_local'
467 INTEGER :: col, coloff, my_ncol, row, rowoff, &
470 REAL(
dp) :: my_alpha, my_alpha2
471 REAL(
dp),
DIMENSION(:, :),
POINTER :: data_d
474 CALL timeset(routinen, timing_handle)
477 IF (
PRESENT(alpha)) my_alpha = alpha
479 my_ncol =
SIZE(vec_b, 2)
480 IF (
PRESENT(ncol)) my_ncol = ncol
494 IF (my_ncol .NE. 1)
THEN
495 CALL dgemm(
'N',
'N', &
496 SIZE(data_d, 1), my_ncol,
SIZE(data_d, 2), &
497 my_alpha, data_d(1, 1),
SIZE(data_d, 1), &
498 vec_b(coloff, 1),
SIZE(vec_b, 1), &
499 1.0_dp, vec_c(rowoff, 1),
SIZE(vec_c, 1))
501 CALL dgemv(
'N',
SIZE(data_d, 1),
SIZE(data_d, 2), &
502 my_alpha, data_d(1, 1),
SIZE(data_d, 1), &
503 vec_b(coloff, 1), 1, &
504 1.0_dp, vec_c(rowoff, 1), 1)
516 IF (row .NE. col)
THEN
517 IF (my_ncol .NE. 1)
THEN
518 CALL dgemm(
'T',
'N', &
519 SIZE(data_d, 2), my_ncol,
SIZE(data_d, 1), &
520 my_alpha2, data_d(1, 1),
SIZE(data_d, 1), &
521 vec_b(rowoff, 1),
SIZE(vec_b, 1), &
522 1.0_dp, vec_c(coloff, 1),
SIZE(vec_c, 1))
524 CALL dgemv(
'T',
SIZE(data_d, 1),
SIZE(data_d, 2), &
525 my_alpha2, data_d(1, 1),
SIZE(data_d, 1), &
526 vec_b(rowoff, 1), 1, &
527 1.0_dp, vec_c(coloff, 1), 1)
534 CALL timestop(timing_handle)
555 INTEGER,
INTENT(IN) :: ncol
556 REAL(
dp),
INTENT(IN),
OPTIONAL :: alpha, beta
558 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_dbcsr_sm_fm_multiply'
560 INTEGER :: a_ncol, a_nrow, b_ncol, b_nrow, c_ncol, &
561 c_nrow, k_in, k_out, timing_handle, &
563 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_blk_size_right_in, &
564 col_blk_size_right_out, col_dist, &
565 row_blk_size, row_dist
568 REAL(
dp) :: my_alpha, my_beta
570 CALL timeset(routinen, timing_handle)
574 IF (
PRESENT(alpha)) my_alpha = alpha
575 IF (
PRESENT(beta)) my_beta = beta
578 CALL cp_fm_get_info(fm_in, ncol_global=b_ncol, nrow_global=b_nrow)
579 CALL cp_fm_get_info(fm_out, ncol_global=c_ncol, nrow_global=c_nrow)
580 CALL dbcsr_get_info(matrix, nfullrows_total=a_nrow, nfullcols_total=a_ncol)
594 IF (ncol .GT. 0 .AND. k_out .GT. 0 .AND. k_in .GT. 0)
THEN
595 CALL dbcsr_get_info(matrix, row_blk_size=row_blk_size, col_blk_size=col_blk_size, distribution=dist)
598 CALL dbcsr_create(in,
"D", dist_right_in, dbcsr_type_no_symmetry, &
599 col_blk_size, col_blk_size_right_in)
604 row_dist=row_dist, col_dist=col_dist)
605 ALLOCATE (col_blk_size_right_out(
SIZE(col_blk_size_right_in)))
606 col_blk_size_right_out = col_blk_size_right_in
607 CALL match_col_sizes(col_blk_size_right_out, col_blk_size_right_in, k_out)
614 CALL dbcsr_create(out,
"D", product_dist, dbcsr_type_no_symmetry, &
615 row_blk_size, col_blk_size_right_out)
618 IF (ncol .NE. k_out .OR. my_beta .NE. 0.0_dp) &
621 CALL timeset(routinen//
'_core', timing_handle_mult)
622 CALL dbcsr_multiply(
"N",
"N", my_alpha, matrix, in, my_beta, out, &
624 CALL timestop(timing_handle_mult)
630 DEALLOCATE (col_blk_size_right_in, col_blk_size_right_out)
636 CALL timestop(timing_handle)
646 SUBROUTINE match_col_sizes(sizes1, sizes2, full_num)
647 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: sizes1
648 INTEGER,
DIMENSION(:),
INTENT(IN) :: sizes2
649 INTEGER,
INTENT(IN) :: full_num
651 INTEGER :: left, n1, n2, p, rm, used
656 cpabort(
"distributions must be equal!")
657 sizes1(1:n1) = sizes2(1:n1)
658 used = sum(sizes1(1:n1))
662 IF (used .LT. full_num)
THEN
663 sizes1(n1) = sizes1(n1) + full_num - used
665 left = used - full_num
667 DO WHILE (left .GT. 0 .AND. p .GT. 0)
668 rm = min(left, sizes1(p))
669 sizes1(p) = sizes1(p) - rm
674 END SUBROUTINE match_col_sizes
695 TYPE(
dbcsr_type),
INTENT(INOUT) :: sparse_matrix
697 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_g
698 INTEGER,
INTENT(IN) :: ncol
699 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: alpha
700 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
701 INTEGER,
INTENT(IN),
OPTIONAL :: symmetry_mode
703 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_dbcsr_plus_fm_fm_t'
705 INTEGER :: k, my_symmetry_mode, nao, npcols, &
707 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size_left, col_dist_left, &
708 row_blk_size, row_dist
709 LOGICAL :: check_product, my_keep_sparsity
710 REAL(kind=
dp) :: my_alpha, norm
714 TYPE(
dbcsr_type) :: mat_g, mat_v, sparse_matrix2, &
717 check_product = .false.
719 CALL timeset(routinen, timing_handle)
721 my_keep_sparsity = .true.
722 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
725 IF (
PRESENT(symmetry_mode)) my_symmetry_mode = symmetry_mode
727 NULLIFY (col_dist_left)
729 IF (ncol .GT. 0)
THEN
731 cpabort(
"sparse_matrix must pre-exist")
738 CALL create_bl_distribution(col_dist_left, col_blk_size_left, k, npcols)
740 row_dist=row_dist, col_dist=col_dist_left)
741 DEALLOCATE (col_dist_left)
743 CALL dbcsr_create(mat_v,
"DBCSR matrix_v", dist_left, dbcsr_type_no_symmetry, &
744 row_blk_size, col_blk_size_left)
749 IF (
PRESENT(matrix_g))
THEN
750 CALL dbcsr_create(mat_g,
"DBCSR matrix_g", dist_left, dbcsr_type_no_symmetry, &
751 row_blk_size, col_blk_size_left)
755 DEALLOCATE (col_blk_size_left)
759 IF (check_product)
THEN
761 CALL cp_fm_struct_create(fm_struct_tmp, context=matrix_v%matrix_struct%context, nrow_global=nao, &
762 ncol_global=nao, para_env=matrix_v%matrix_struct%para_env)
763 CALL cp_fm_create(fm_matrix, fm_struct_tmp, name=
"fm matrix")
766 CALL dbcsr_copy(sparse_matrix3, sparse_matrix)
770 IF (
PRESENT(alpha)) my_alpha = alpha
771 IF (
PRESENT(matrix_g))
THEN
772 IF (my_symmetry_mode == 1)
THEN
775 1.0_dp, sparse_matrix, &
776 retain_sparsity=my_keep_sparsity, &
779 1.0_dp, sparse_matrix, &
780 retain_sparsity=my_keep_sparsity, &
782 ELSE IF (my_symmetry_mode == -1)
THEN
785 1.0_dp, sparse_matrix, &
786 retain_sparsity=my_keep_sparsity, &
789 1.0_dp, sparse_matrix, &
790 retain_sparsity=my_keep_sparsity, &
795 1.0_dp, sparse_matrix, &
796 retain_sparsity=my_keep_sparsity, &
801 1.0_dp, sparse_matrix, &
802 retain_sparsity=my_keep_sparsity, &
806 IF (check_product)
THEN
807 IF (
PRESENT(matrix_g))
THEN
808 IF (my_symmetry_mode == 1)
THEN
809 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_v, matrix_g, &
811 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_g, matrix_v, &
813 ELSE IF (my_symmetry_mode == -1)
THEN
814 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_v, matrix_g, &
816 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, -0.5_dp*my_alpha, matrix_g, matrix_v, &
819 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, my_alpha, matrix_v, matrix_g, &
823 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, my_alpha, matrix_v, matrix_v, &
827 CALL dbcsr_copy(sparse_matrix2, sparse_matrix)
828 CALL dbcsr_scale(sparse_matrix2, alpha_scalar=0.0_dp)
829 CALL copy_fm_to_dbcsr(fm_matrix, sparse_matrix2, keep_sparsity=my_keep_sparsity)
830 CALL dbcsr_add(sparse_matrix2, sparse_matrix, alpha_scalar=1.0_dp, &
833 WRITE (*, *)
'nao=', nao,
' k=', k,
' ncol=', ncol,
' my_alpha=', my_alpha
834 WRITE (*, *)
'PRESENT (matrix_g)',
PRESENT(matrix_g)
836 WRITE (*, *)
'norm(sm+alpha*v*g^t - fm+alpha*v*g^t)/n=', norm/real(nao,
dp)
837 IF (norm/real(nao,
dp) .GT. 1e-12_dp)
THEN
863 CALL timestop(timing_handle)
883 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size_right_in, row_blk_size
891 CALL dbcsr_create(matrix,
"D", dist_right_in, dbcsr_type_no_symmetry, &
892 row_blk_size, col_blk_size_right_in)
895 DEALLOCATE (col_blk_size_right_in)
912 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix, template
913 INTEGER,
INTENT(IN) :: m, n
914 CHARACTER,
INTENT(IN),
OPTIONAL :: sym
917 INTEGER :: npcols, nprows
918 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_dist, row_blk_size, &
922 CALL dbcsr_get_info(template, matrix_type=mysym, distribution=tmpl_dist)
924 IF (
PRESENT(sym)) mysym = sym
926 NULLIFY (row_dist, col_dist)
927 NULLIFY (row_blk_size, col_blk_size)
931 CALL create_bl_distribution(row_dist, row_blk_size, m, nprows)
932 CALL create_bl_distribution(col_dist, col_blk_size, n, npcols)
934 row_dist=row_dist, col_dist=col_dist, &
938 CALL dbcsr_create(matrix,
"m_n_template", dist_m_n, mysym, &
939 row_blk_size, col_blk_size, reuse_arrays=.true.)
955 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix, template
957 CHARACTER,
OPTIONAL :: sym
961 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_dist, row_blk_size, &
966 IF (
PRESENT(sym)) mysym = sym
973 NULLIFY (col_dist, col_blk_size)
974 CALL create_bl_distribution(col_dist, col_blk_size, n, npcols)
976 row_dist=row_dist, col_dist=col_dist)
979 CALL dbcsr_create(matrix,
"m_n_template", dist_m_n, mysym, row_blk_size, col_blk_size)
981 DEALLOCATE (col_dist, col_blk_size)
996 SUBROUTINE create_bl_distribution(block_distribution, &
997 block_size, nelements, nbins)
998 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: block_distribution, block_size
999 INTEGER,
INTENT(IN) :: nelements, nbins
1001 CHARACTER(len=*),
PARAMETER :: routinen =
'create_bl_distribution', &
1002 routinep = modulen//
':'//routinen
1004 INTEGER :: bin, blk_layer, element_stack, els, &
1005 estimated_blocks, max_blocks_per_bin, &
1006 nblks, nblocks, stat
1007 INTEGER,
DIMENSION(:),
POINTER :: blk_dist, blk_sizes
1011 NULLIFY (block_distribution)
1012 NULLIFY (block_size)
1014 IF (nelements .GT. 0)
THEN
1017 max_blocks_per_bin = ceiling(real(nblocks, kind=
dp)/real(nbins, kind=
dp))
1020 WRITE (*,
'(1X,A,1X,A,I7,A,I7,A)') routinep,
"For", nelements, &
1021 " elements and", nbins,
" bins"
1022 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1024 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1026 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1027 max_blocks_per_bin,
" max blocks/bin"
1030 estimated_blocks = max_blocks_per_bin*nbins
1031 ALLOCATE (blk_dist(estimated_blocks), stat=stat)
1034 ALLOCATE (blk_sizes(estimated_blocks), stat=stat)
1036 cpabort(
"blk_sizes")
1039 DO blk_layer = 1, max_blocks_per_bin
1040 DO bin = 0, nbins - 1
1042 IF (els .GT. 0)
THEN
1043 element_stack = element_stack + els
1045 blk_dist(nblks) = bin
1046 blk_sizes(nblks) = els
1047 IF (debug_mod)
WRITE (*,
'(1X,A,I5,A,I5,A,I5)') routinep//
" Assigning", &
1048 els,
" elements as block", nblks,
" to bin", bin
1053 IF (nblks .EQ. estimated_blocks)
THEN
1054 block_distribution => blk_dist
1055 block_size => blk_sizes
1057 ALLOCATE (block_distribution(nblks), stat=stat)
1060 block_distribution(:) = blk_dist(1:nblks)
1061 DEALLOCATE (blk_dist)
1062 ALLOCATE (block_size(nblks), stat=stat)
1064 cpabort(
"blk_sizes")
1065 block_size(:) = blk_sizes(1:nblks)
1066 DEALLOCATE (blk_sizes)
1069 ALLOCATE (block_distribution(0), stat=stat)
1072 ALLOCATE (block_size(0), stat=stat)
1074 cpabort(
"blk_sizes")
10761579
FORMAT(i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5)
1078 WRITE (*,
'(1X,A,A)') routinep//
" Distribution"
1079 WRITE (*, 1579) block_distribution(:)
1080 WRITE (*,
'(1X,A,A)') routinep//
" Sizes"
1081 WRITE (*, 1579) block_size(:)
1083 END SUBROUTINE create_bl_distribution
1097 right_col_blk_sizes)
1100 INTEGER,
INTENT(IN) :: ncolumns
1101 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: right_col_blk_sizes
1103 INTEGER :: multiplicity, ncols, nimages, npcols, &
1105 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: tmp_images
1106 INTEGER,
DIMENSION(:),
POINTER :: old_col_dist, right_col_dist, &
1111 col_dist=old_col_dist, &
1116 CALL create_bl_distribution(right_col_dist, right_col_blk_sizes, ncolumns, npcols)
1118 ALLOCATE (right_row_dist(ncols), tmp_images(ncols))
1119 nimages =
lcm(nprows, npcols)/nprows
1120 multiplicity = nprows/
gcd(nprows, npcols)
1121 CALL rebin_distribution(right_row_dist, tmp_images, old_col_dist, nprows, multiplicity, nimages)
1124 template=dist_left, &
1125 row_dist=right_row_dist, &
1126 col_dist=right_col_dist, &
1129 reuse_arrays=.true.)
1130 DEALLOCATE (tmp_images)
1166 SUBROUTINE rebin_distribution(new_bins, images, source_bins, &
1167 nbins, multiplicity, nimages)
1168 INTEGER,
DIMENSION(:),
INTENT(OUT) :: new_bins, images
1169 INTEGER,
DIMENSION(:),
INTENT(IN) :: source_bins
1170 INTEGER,
INTENT(IN) :: nbins, multiplicity, nimages
1172 INTEGER :: bin, i, old_nbins, virtual_bin
1173 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: bin_multiplier
1177 IF (mod(nbins*nimages, multiplicity) .NE. 0)
THEN
1178 cpwarn(
"mulitplicity is not divisor of new process grid coordinate")
1180 old_nbins = (nbins*nimages)/multiplicity
1181 ALLOCATE (bin_multiplier(0:old_nbins - 1))
1182 bin_multiplier(:) = 0
1183 DO i = 1,
SIZE(new_bins)
1184 IF (i .LE.
SIZE(source_bins))
THEN
1185 bin = source_bins(i)
1188 bin = mod(i, old_nbins)
1190 virtual_bin = bin*multiplicity + bin_multiplier(bin)
1191 new_bins(i) = virtual_bin/nimages
1192 images(i) = 1 + mod(virtual_bin, nimages)
1193 bin_multiplier(bin) = bin_multiplier(bin) + 1
1194 IF (bin_multiplier(bin) .GE. multiplicity)
THEN
1195 bin_multiplier(bin) = 0
1198 END SUBROUTINE rebin_distribution
1215 SUBROUTINE dbcsr_create_dist_block_cyclic(dist, nrows, ncolumns, &
1216 nrow_block, ncol_block, group_handle, pgrid, row_blk_sizes, col_blk_sizes)
1218 INTEGER,
INTENT(IN) :: nrows, ncolumns, nrow_block, ncol_block, &
1220 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
1221 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: row_blk_sizes, col_blk_sizes
1223 CHARACTER(len=*),
PARAMETER :: routinen =
'dbcsr_create_dist_block_cyclic'
1225 INTEGER :: nblkcols, nblkrows, npcols, nprows, &
1227 INTEGER,
DIMENSION(:),
POINTER :: cd_data, rd_data
1230 IF (nrow_block .EQ. 0)
THEN
1234 nblkrows = nrows/nrow_block
1235 sz = mod(nrows, nrow_block)
1237 IF (sz .GT. 0) nblkrows = nblkrows + 1
1238 ALLOCATE (row_blk_sizes(nblkrows), rd_data(nblkrows))
1239 row_blk_sizes = nrow_block
1240 IF (sz .NE. 0) row_blk_sizes(nblkrows) = sz
1243 IF (ncol_block .EQ. 0)
THEN
1247 nblkcols = ncolumns/ncol_block
1248 sz = mod(ncolumns, ncol_block)
1250 IF (sz .GT. 0) nblkcols = nblkcols + 1
1251 ALLOCATE (col_blk_sizes(nblkcols), cd_data(nblkcols))
1252 col_blk_sizes = ncol_block
1253 IF (sz .NE. 0) col_blk_sizes(nblkcols) = sz
1256 WRITE (*, *) routinen//
" nrows,nrow_block,nblkrows=", &
1257 nrows, nrow_block, nblkrows
1258 WRITE (*, *) routinen//
" ncols,ncol_block,nblkcols=", &
1259 ncolumns, ncol_block, nblkcols
1262 nprows =
SIZE(pgrid, 1)
1263 DO pdim = 0, min(nprows - 1, nblkrows - 1)
1264 rd_data(1 + pdim:nblkrows:nprows) = pdim
1267 npcols =
SIZE(pgrid, 2)
1268 DO pdim = 0, min(npcols - 1, nblkcols - 1)
1269 cd_data(1 + pdim:nblkcols:npcols) = pdim
1273 WRITE (*, *) routinen//
" row_dist", &
1275 WRITE (*, *) routinen//
" col_dist", &
1280 group=group_handle, pgrid=pgrid, &
1283 reuse_arrays=.true.)
1285 END SUBROUTINE dbcsr_create_dist_block_cyclic
1294 SUBROUTINE allocate_dbcsr_matrix_set_1d(matrix_set, nmatrix)
1295 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_set
1296 INTEGER,
INTENT(IN) :: nmatrix
1301 ALLOCATE (matrix_set(nmatrix))
1302 DO imatrix = 1, nmatrix
1303 NULLIFY (matrix_set(imatrix)%matrix)
1305 END SUBROUTINE allocate_dbcsr_matrix_set_1d
1315 SUBROUTINE allocate_dbcsr_matrix_set_2d(matrix_set, nmatrix, mmatrix)
1316 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_set
1317 INTEGER,
INTENT(IN) :: nmatrix, mmatrix
1319 INTEGER :: imatrix, jmatrix
1322 ALLOCATE (matrix_set(nmatrix, mmatrix))
1323 DO jmatrix = 1, mmatrix
1324 DO imatrix = 1, nmatrix
1325 NULLIFY (matrix_set(imatrix, jmatrix)%matrix)
1328 END SUBROUTINE allocate_dbcsr_matrix_set_2d
1339 SUBROUTINE allocate_dbcsr_matrix_set_3d(matrix_set, nmatrix, mmatrix, pmatrix)
1340 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :),
POINTER :: matrix_set
1341 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix
1343 INTEGER :: imatrix, jmatrix, kmatrix
1346 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix))
1347 DO kmatrix = 1, pmatrix
1348 DO jmatrix = 1, mmatrix
1349 DO imatrix = 1, nmatrix
1350 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix)%matrix)
1354 END SUBROUTINE allocate_dbcsr_matrix_set_3d
1366 SUBROUTINE allocate_dbcsr_matrix_set_4d(matrix_set, nmatrix, mmatrix, pmatrix, qmatrix)
1367 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :, :),
POINTER :: matrix_set
1368 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix, qmatrix
1370 INTEGER :: imatrix, jmatrix, kmatrix, lmatrix
1373 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix, qmatrix))
1374 DO lmatrix = 1, qmatrix
1375 DO kmatrix = 1, pmatrix
1376 DO jmatrix = 1, mmatrix
1377 DO imatrix = 1, nmatrix
1378 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix, lmatrix)%matrix)
1383 END SUBROUTINE allocate_dbcsr_matrix_set_4d
1396 SUBROUTINE allocate_dbcsr_matrix_set_5d(matrix_set, nmatrix, mmatrix, pmatrix, qmatrix, smatrix)
1398 POINTER :: matrix_set
1399 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix, qmatrix, &
1402 INTEGER :: hmatrix, imatrix, jmatrix, kmatrix, &
1406 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix, qmatrix, smatrix))
1407 DO hmatrix = 1, smatrix
1408 DO lmatrix = 1, qmatrix
1409 DO kmatrix = 1, pmatrix
1410 DO jmatrix = 1, mmatrix
1411 DO imatrix = 1, nmatrix
1412 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix, lmatrix, hmatrix)%matrix)
1418 END SUBROUTINE allocate_dbcsr_matrix_set_5d
1426 SUBROUTINE deallocate_dbcsr_matrix_set_1d(matrix_set)
1428 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_set
1432 IF (
ASSOCIATED(matrix_set))
THEN
1433 DO imatrix = 1,
SIZE(matrix_set)
1436 DEALLOCATE (matrix_set)
1439 END SUBROUTINE deallocate_dbcsr_matrix_set_1d
1447 SUBROUTINE deallocate_dbcsr_matrix_set_2d(matrix_set)
1449 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_set
1451 INTEGER :: imatrix, jmatrix
1453 IF (
ASSOCIATED(matrix_set))
THEN
1454 DO jmatrix = 1,
SIZE(matrix_set, 2)
1455 DO imatrix = 1,
SIZE(matrix_set, 1)
1459 DEALLOCATE (matrix_set)
1461 END SUBROUTINE deallocate_dbcsr_matrix_set_2d
1469 SUBROUTINE deallocate_dbcsr_matrix_set_3d(matrix_set)
1471 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :),
POINTER :: matrix_set
1473 INTEGER :: imatrix, jmatrix, kmatrix
1475 IF (
ASSOCIATED(matrix_set))
THEN
1476 DO kmatrix = 1,
SIZE(matrix_set, 3)
1477 DO jmatrix = 1,
SIZE(matrix_set, 2)
1478 DO imatrix = 1,
SIZE(matrix_set, 1)
1483 DEALLOCATE (matrix_set)
1485 END SUBROUTINE deallocate_dbcsr_matrix_set_3d
1493 SUBROUTINE deallocate_dbcsr_matrix_set_4d(matrix_set)
1495 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :, :),
POINTER :: matrix_set
1497 INTEGER :: imatrix, jmatrix, kmatrix, lmatrix
1499 IF (
ASSOCIATED(matrix_set))
THEN
1500 DO lmatrix = 1,
SIZE(matrix_set, 4)
1501 DO kmatrix = 1,
SIZE(matrix_set, 3)
1502 DO jmatrix = 1,
SIZE(matrix_set, 2)
1503 DO imatrix = 1,
SIZE(matrix_set, 1)
1509 DEALLOCATE (matrix_set)
1511 END SUBROUTINE deallocate_dbcsr_matrix_set_4d
1519 SUBROUTINE deallocate_dbcsr_matrix_set_5d(matrix_set)
1522 POINTER :: matrix_set
1524 INTEGER :: hmatrix, imatrix, jmatrix, kmatrix, &
1527 IF (
ASSOCIATED(matrix_set))
THEN
1528 DO hmatrix = 1,
SIZE(matrix_set, 5)
1529 DO lmatrix = 1,
SIZE(matrix_set, 4)
1530 DO kmatrix = 1,
SIZE(matrix_set, 3)
1531 DO jmatrix = 1,
SIZE(matrix_set, 2)
1532 DO imatrix = 1,
SIZE(matrix_set, 1)
1539 DEALLOCATE (matrix_set)
1541 END SUBROUTINE deallocate_dbcsr_matrix_set_5d
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
methods related to the blacs parallel environment
subroutine, public dbcsr_verify_matrix(matrix, verbosity, local)
...
subroutine, public dbcsr_distribution_release(dist)
...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_distribution_new(dist, template, group, pgrid, row_dist, col_dist, reuse_arrays)
...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset)
...
character function, public dbcsr_get_matrix_type(matrix)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
logical function, public dbcsr_valid_index(matrix)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
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_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_complete_redistribute(matrix, redist)
...
subroutine, public dbcsr_iterator_readonly_start(iterator, matrix, shared, dynamic, dynamic_byrows)
Like dbcsr_iterator_start() but with matrix being INTENT(IN). When invoking this routine,...
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)
...
subroutine, public dbcsr_reserve_all_blocks(matrix)
Reserves all blocks.
real(dp) function, public dbcsr_frobenius_norm(matrix)
Compute the frobenius norm of a dbcsr matrix.
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
integer, save, public max_elements_per_block
subroutine, public dbcsr_create_dist_r_unrot(dist_right, dist_left, ncolumns, right_col_blk_sizes)
Creates a new distribution for the right matrix in a matrix multiplication with unrotated grid.
subroutine, public dbcsr_multiply_local(matrix_a, vec_b, vec_c, ncol, alpha)
multiply a dbcsr with a replicated array c = alpha_scalar * A (dbscr) * b + c
subroutine, public cp_dbcsr_dist2d_to_dist(dist2d, dist)
Creates a DBCSR distribution from a distribution_2d.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr_bc(fm, bc_mat)
Copy a BLACS matrix to a dbcsr matrix with a special block-cyclic distribution, which requires no com...
subroutine, public copy_dbcsr_to_fm_bc(bc_mat, fm)
Copy a DBCSR_BLACS matrix to a BLACS matrix.
subroutine, public cp_fm_to_dbcsr_row_template(matrix, fm_in, template)
Utility function to copy a specially shaped fm to dbcsr_matrix The result matrix will be the matrix i...
subroutine, public cp_dbcsr_m_by_n_from_row_template(matrix, template, n, sym)
Utility function to create dbcsr matrix, m x n matrix (n arbitrary) with the same processor grid and ...
subroutine, public cp_dbcsr_plus_fm_fm_t(sparse_matrix, matrix_v, matrix_g, ncol, alpha, keep_sparsity, symmetry_mode)
performs the multiplication sparse_matrix+dense_mat*dens_mat^T if matrix_g is not explicitly given,...
subroutine, public cp_dbcsr_m_by_n_from_template(matrix, template, m, n, sym)
Utility function to create an arbitrary shaped dbcsr matrix with the same processor grid as the templ...
subroutine, public dbcsr_copy_columns_hack(matrix_b, matrix_a, ncol, source_start, target_start, para_env, blacs_env)
hack for dbcsr_copy_columns
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
basic linear algebra operations for full matrices
subroutine, public cp_fm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, c_first_row)
computes matrix_c = beta * matrix_c + alpha * ( matrix_a ** transa ) * ( matrix_b ** transb )
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
subroutine, public distribution_2d_get(distribution_2d, row_distribution, col_distribution, n_row_distribution, n_col_distribution, n_local_rows, n_local_cols, local_rows, local_cols, flat_local_rows, flat_local_cols, n_flat_local_rows, n_flat_local_cols, blacs_env)
returns various attributes about the distribution_2d
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Collection of simple mathematical functions and subroutines.
elemental integer function, public lcm(a, b)
computes the least common multiplier of two numbers
elemental integer function, public gcd(a, b)
computes the greatest common divisor of two number
Interface to the message passing library MPI.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
distributes pairs on a 2d grid of processors
stores all the informations relevant to an mpi environment