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)
166 pgrid => fm%matrix_struct%context%blacs2mpi
169 nrow_block = fm%matrix_struct%nrow_block
170 ncol_block = fm%matrix_struct%ncol_block
171 nrow_global = fm%matrix_struct%nrow_global
172 ncol_global = fm%matrix_struct%ncol_global
173 NULLIFY (col_blk_size, row_blk_size)
174 CALL dbcsr_create_dist_block_cyclic(bc_dist, &
175 nrows=nrow_global, ncolumns=ncol_global, &
176 nrow_block=nrow_block, ncol_block=ncol_block, &
177 group_handle=fm%matrix_struct%para_env%get_handle(), pgrid=pgrid, &
178 row_blk_sizes=row_blk_size, col_blk_sizes=col_blk_size)
182 dbcsr_type_no_symmetry, row_blk_size, col_blk_size, reuse_arrays=.true.)
188 CALL calculate_fm_block_ranges(bc_mat, first_row, last_row, first_col, last_col)
192 fm_block => fm%local_data
198 dbcsr_block(:, :) = fm_block(first_row(row):last_row(row), first_col(col):last_col(col))
203 CALL timestop(handle)
215 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_dbcsr_to_fm'
217 CHARACTER(len=default_string_length) :: name
218 INTEGER :: group_handle, handle, ncol_block, &
219 nfullcols_total, nfullrows_total, &
221 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, row_blk_size
222 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
226 CALL timeset(routinen, handle)
232 nfullrows_total=nfullrows_total, &
233 nfullcols_total=nfullcols_total)
235 cpassert(fm%matrix_struct%nrow_global == nfullrows_total)
236 cpassert(fm%matrix_struct%ncol_global == nfullcols_total)
239 nrow_block = fm%matrix_struct%nrow_block
240 ncol_block = fm%matrix_struct%ncol_block
243 NULLIFY (col_blk_size, row_blk_size)
245 CALL dbcsr_create_dist_block_cyclic(bc_dist, &
246 nrows=nfullrows_total, ncolumns=nfullcols_total, &
247 nrow_block=nrow_block, ncol_block=ncol_block, &
248 group_handle=group_handle, pgrid=pgrid, &
249 row_blk_sizes=row_blk_size, col_blk_sizes=col_blk_size)
251 CALL dbcsr_create(bc_mat,
"Block-cyclic"//name, bc_dist, &
252 dbcsr_type_no_symmetry, row_blk_size, col_blk_size, reuse_arrays=.true.)
255 CALL dbcsr_create(matrix_nosym, template=matrix, matrix_type=
"N")
264 CALL timestop(handle)
276 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_dbcsr_to_fm_bc'
278 INTEGER :: col, handle, row
279 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: first_col, first_row, last_col, last_row
280 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: dbcsr_block, fm_block
283 CALL timeset(routinen, handle)
285 CALL calculate_fm_block_ranges(bc_mat, first_row, last_row, first_col, last_col)
288 fm_block => fm%local_data
289 fm_block = real(0.0, kind=
dp)
295 fm_block(first_row(row):last_row(row), first_col(col):last_col(col)) = dbcsr_block(:, :)
300 CALL timestop(handle)
312 SUBROUTINE calculate_fm_block_ranges(bc_mat, first_row, last_row, first_col, last_col)
314 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: first_row, last_row, first_col, last_col
316 INTEGER :: col, nblkcols_local, nblkcols_total, &
317 nblkrows_local, nblkrows_total, row
318 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: local_col_sizes, local_row_sizes
319 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, local_cols, local_rows, &
323 nblkrows_total=nblkrows_total, &
324 nblkcols_total=nblkcols_total, &
325 nblkrows_local=nblkrows_local, &
326 nblkcols_local=nblkcols_local, &
327 local_rows=local_rows, &
328 local_cols=local_cols, &
329 row_blk_size=row_blk_size, &
330 col_blk_size=col_blk_size)
333 ALLOCATE (local_row_sizes(nblkrows_total))
334 local_row_sizes(:) = 0
335 IF (nblkrows_local >= 1)
THEN
336 DO row = 1, nblkrows_local
337 local_row_sizes(local_rows(row)) = row_blk_size(local_rows(row))
340 ALLOCATE (first_row(nblkrows_total), last_row(nblkrows_total))
341 CALL dbcsr_convert_sizes_to_offsets(local_row_sizes, first_row, last_row)
342 DEALLOCATE (local_row_sizes)
345 ALLOCATE (local_col_sizes(nblkcols_total))
346 local_col_sizes(:) = 0
347 IF (nblkcols_local >= 1)
THEN
348 DO col = 1, nblkcols_local
349 local_col_sizes(local_cols(col)) = col_blk_size(local_cols(col))
352 ALLOCATE (first_col(nblkcols_total), last_col(nblkcols_total))
353 CALL dbcsr_convert_sizes_to_offsets(local_col_sizes, first_col, last_col)
354 DEALLOCATE (local_col_sizes)
356 END SUBROUTINE calculate_fm_block_ranges
370 ncol, source_start, target_start, para_env, blacs_env)
374 INTEGER,
INTENT(IN) :: ncol, source_start, target_start
378 INTEGER :: nfullcols_total, nfullrows_total
383 CALL dbcsr_get_info(matrix_a, nfullrows_total=nfullrows_total, nfullcols_total=nfullcols_total)
385 ncol_global=nfullcols_total, para_env=para_env)
386 CALL cp_fm_create(fm_matrix_a, fm_struct, name=
"fm_matrix_a")
389 CALL dbcsr_get_info(matrix_b, nfullrows_total=nfullrows_total, nfullcols_total=nfullcols_total)
391 ncol_global=nfullcols_total, para_env=para_env)
392 CALL cp_fm_create(fm_matrix_b, fm_struct, name=
"fm_matrix_b")
398 CALL cp_fm_to_fm(fm_matrix_a, fm_matrix_b, ncol, source_start, target_start)
418 INTEGER,
DIMENSION(:),
POINTER :: col_dist, row_dist
419 INTEGER,
DIMENSION(:, :),
POINTER :: col_dist_data, pgrid, row_dist_data
426 row_distribution=row_dist_data, &
427 col_distribution=col_dist_data, &
429 CALL blacs_env%get(para_env=para_env, blacs2mpi=pgrid)
432 row_dist => row_dist_data(:, 1)
433 col_dist => col_dist_data(:, 1)
438 group=para_env%get_handle(), pgrid=pgrid, &
456 REAL(
dp),
DIMENSION(:, :),
INTENT(IN) :: vec_b
457 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT) :: vec_c
458 INTEGER,
INTENT(in),
OPTIONAL :: ncol
459 REAL(
dp),
INTENT(IN),
OPTIONAL :: alpha
461 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_multiply_local'
463 INTEGER :: col, coloff, my_ncol, row, rowoff, &
466 REAL(
dp) :: my_alpha, my_alpha2
467 REAL(
dp),
DIMENSION(:, :),
POINTER :: data_d
470 CALL timeset(routinen, timing_handle)
473 IF (
PRESENT(alpha)) my_alpha = alpha
475 my_ncol =
SIZE(vec_b, 2)
476 IF (
PRESENT(ncol)) my_ncol = ncol
490 IF (my_ncol /= 1)
THEN
491 CALL dgemm(
'N',
'N', &
492 SIZE(data_d, 1), my_ncol,
SIZE(data_d, 2), &
493 my_alpha, data_d(1, 1),
SIZE(data_d, 1), &
494 vec_b(coloff, 1),
SIZE(vec_b, 1), &
495 1.0_dp, vec_c(rowoff, 1),
SIZE(vec_c, 1))
497 CALL dgemv(
'N',
SIZE(data_d, 1),
SIZE(data_d, 2), &
498 my_alpha, data_d(1, 1),
SIZE(data_d, 1), &
499 vec_b(coloff, 1), 1, &
500 1.0_dp, vec_c(rowoff, 1), 1)
513 IF (my_ncol /= 1)
THEN
514 CALL dgemm(
'T',
'N', &
515 SIZE(data_d, 2), my_ncol,
SIZE(data_d, 1), &
516 my_alpha2, data_d(1, 1),
SIZE(data_d, 1), &
517 vec_b(rowoff, 1),
SIZE(vec_b, 1), &
518 1.0_dp, vec_c(coloff, 1),
SIZE(vec_c, 1))
520 CALL dgemv(
'T',
SIZE(data_d, 1),
SIZE(data_d, 2), &
521 my_alpha2, data_d(1, 1),
SIZE(data_d, 1), &
522 vec_b(rowoff, 1), 1, &
523 1.0_dp, vec_c(coloff, 1), 1)
530 CALL timestop(timing_handle)
551 INTEGER,
INTENT(IN) :: ncol
552 REAL(
dp),
INTENT(IN),
OPTIONAL :: alpha, beta
554 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_dbcsr_sm_fm_multiply'
556 INTEGER :: a_ncol, a_nrow, b_ncol, b_nrow, c_ncol, &
557 c_nrow, k_in, k_out, timing_handle, &
559 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_blk_size_right_in, &
560 col_blk_size_right_out, col_dist, &
561 row_blk_size, row_dist
564 REAL(
dp) :: my_alpha, my_beta
566 CALL timeset(routinen, timing_handle)
570 IF (
PRESENT(alpha)) my_alpha = alpha
571 IF (
PRESENT(beta)) my_beta = beta
574 CALL cp_fm_get_info(fm_in, ncol_global=b_ncol, nrow_global=b_nrow)
575 CALL cp_fm_get_info(fm_out, ncol_global=c_ncol, nrow_global=c_nrow)
576 CALL dbcsr_get_info(matrix, nfullrows_total=a_nrow, nfullcols_total=a_ncol)
590 IF (ncol > 0 .AND. k_out > 0 .AND. k_in > 0)
THEN
591 CALL dbcsr_get_info(matrix, row_blk_size=row_blk_size, col_blk_size=col_blk_size, distribution=dist)
594 CALL dbcsr_create(in,
"D", dist_right_in, dbcsr_type_no_symmetry, &
595 col_blk_size, col_blk_size_right_in)
600 row_dist=row_dist, col_dist=col_dist)
601 ALLOCATE (col_blk_size_right_out(
SIZE(col_blk_size_right_in)))
602 col_blk_size_right_out = col_blk_size_right_in
603 CALL match_col_sizes(col_blk_size_right_out, col_blk_size_right_in, k_out)
610 CALL dbcsr_create(out,
"D", product_dist, dbcsr_type_no_symmetry, &
611 row_blk_size, col_blk_size_right_out)
614 IF (ncol /= k_out .OR. my_beta /= 0.0_dp)
THEN
618 CALL timeset(routinen//
'_core', timing_handle_mult)
619 CALL dbcsr_multiply(
"N",
"N", my_alpha, matrix, in, my_beta, out, &
621 CALL timestop(timing_handle_mult)
627 DEALLOCATE (col_blk_size_right_in, col_blk_size_right_out)
633 CALL timestop(timing_handle)
643 SUBROUTINE match_col_sizes(sizes1, sizes2, full_num)
644 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: sizes1
645 INTEGER,
DIMENSION(:),
INTENT(IN) :: sizes2
646 INTEGER,
INTENT(IN) :: full_num
648 INTEGER :: left, n1, n2, p, rm, used
653 cpabort(
"distributions must be equal!")
655 sizes1(1:n1) = sizes2(1:n1)
656 used = sum(sizes1(1:n1))
660 IF (used < full_num)
THEN
661 sizes1(n1) = sizes1(n1) + full_num - used
663 left = used - full_num
665 DO WHILE (left > 0 .AND. p > 0)
666 rm = min(left, sizes1(p))
667 sizes1(p) = sizes1(p) - rm
672 END SUBROUTINE match_col_sizes
693 TYPE(
dbcsr_type),
INTENT(INOUT) :: sparse_matrix
695 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_g
696 INTEGER,
INTENT(IN) :: ncol
697 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: alpha
698 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
699 INTEGER,
INTENT(IN),
OPTIONAL :: symmetry_mode
701 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_dbcsr_plus_fm_fm_t'
703 INTEGER :: k, my_symmetry_mode, nao, npcols, &
705 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size_left, col_dist_left, &
706 row_blk_size, row_dist
707 LOGICAL :: check_product, my_keep_sparsity
708 REAL(kind=
dp) :: my_alpha, norm
712 TYPE(
dbcsr_type) :: mat_g, mat_v, sparse_matrix2, &
715 check_product = .false.
717 CALL timeset(routinen, timing_handle)
719 my_keep_sparsity = .true.
720 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
723 IF (
PRESENT(symmetry_mode)) my_symmetry_mode = symmetry_mode
725 NULLIFY (col_dist_left)
729 cpabort(
"sparse_matrix must pre-exist")
737 CALL create_bl_distribution(col_dist_left, col_blk_size_left, k, npcols)
739 row_dist=row_dist, col_dist=col_dist_left)
740 DEALLOCATE (col_dist_left)
742 CALL dbcsr_create(mat_v,
"DBCSR matrix_v", dist_left, dbcsr_type_no_symmetry, &
743 row_blk_size, col_blk_size_left)
748 IF (
PRESENT(matrix_g))
THEN
749 CALL dbcsr_create(mat_g,
"DBCSR matrix_g", dist_left, dbcsr_type_no_symmetry, &
750 row_blk_size, col_blk_size_left)
754 DEALLOCATE (col_blk_size_left)
758 IF (check_product)
THEN
760 CALL cp_fm_struct_create(fm_struct_tmp, context=matrix_v%matrix_struct%context, nrow_global=nao, &
761 ncol_global=nao, para_env=matrix_v%matrix_struct%para_env)
762 CALL cp_fm_create(fm_matrix, fm_struct_tmp, name=
"fm matrix")
765 CALL dbcsr_copy(sparse_matrix3, sparse_matrix)
769 IF (
PRESENT(alpha)) my_alpha = alpha
770 IF (
PRESENT(matrix_g))
THEN
771 IF (my_symmetry_mode == 1)
THEN
774 1.0_dp, sparse_matrix, &
775 retain_sparsity=my_keep_sparsity, &
778 1.0_dp, sparse_matrix, &
779 retain_sparsity=my_keep_sparsity, &
781 ELSE IF (my_symmetry_mode == -1)
THEN
784 1.0_dp, sparse_matrix, &
785 retain_sparsity=my_keep_sparsity, &
788 1.0_dp, sparse_matrix, &
789 retain_sparsity=my_keep_sparsity, &
794 1.0_dp, sparse_matrix, &
795 retain_sparsity=my_keep_sparsity, &
800 1.0_dp, sparse_matrix, &
801 retain_sparsity=my_keep_sparsity, &
805 IF (check_product)
THEN
806 IF (
PRESENT(matrix_g))
THEN
807 IF (my_symmetry_mode == 1)
THEN
808 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_v, matrix_g, &
810 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_g, matrix_v, &
812 ELSE IF (my_symmetry_mode == -1)
THEN
813 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_v, matrix_g, &
815 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, -0.5_dp*my_alpha, matrix_g, matrix_v, &
818 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, my_alpha, matrix_v, matrix_g, &
822 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, my_alpha, matrix_v, matrix_v, &
826 CALL dbcsr_copy(sparse_matrix2, sparse_matrix)
827 CALL dbcsr_scale(sparse_matrix2, alpha_scalar=0.0_dp)
828 CALL copy_fm_to_dbcsr(fm_matrix, sparse_matrix2, keep_sparsity=my_keep_sparsity)
829 CALL dbcsr_add(sparse_matrix2, sparse_matrix, alpha_scalar=1.0_dp, &
832 WRITE (*, *)
'nao=', nao,
' k=', k,
' ncol=', ncol,
' my_alpha=', my_alpha
833 WRITE (*, *)
'PRESENT (matrix_g)',
PRESENT(matrix_g)
835 WRITE (*, *)
'norm(sm+alpha*v*g^t - fm+alpha*v*g^t)/n=', norm/real(nao,
dp)
843 CALL timestop(timing_handle)
863 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size_right_in, row_blk_size
871 CALL dbcsr_create(matrix,
"D", dist_right_in, dbcsr_type_no_symmetry, &
872 row_blk_size, col_blk_size_right_in)
875 DEALLOCATE (col_blk_size_right_in)
892 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix, template
893 INTEGER,
INTENT(IN) :: m, n
894 CHARACTER,
INTENT(IN),
OPTIONAL :: sym
897 INTEGER :: npcols, nprows
898 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_dist, row_blk_size, &
902 CALL dbcsr_get_info(template, matrix_type=mysym, distribution=tmpl_dist)
904 IF (
PRESENT(sym)) mysym = sym
906 NULLIFY (row_dist, col_dist)
907 NULLIFY (row_blk_size, col_blk_size)
911 CALL create_bl_distribution(row_dist, row_blk_size, m, nprows)
912 CALL create_bl_distribution(col_dist, col_blk_size, n, npcols)
914 row_dist=row_dist, col_dist=col_dist, &
918 CALL dbcsr_create(matrix,
"m_n_template", dist_m_n, mysym, &
919 row_blk_size, col_blk_size, reuse_arrays=.true.)
935 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix, template
937 CHARACTER,
OPTIONAL :: sym
941 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_dist, row_blk_size, &
946 IF (
PRESENT(sym)) mysym = sym
953 NULLIFY (col_dist, col_blk_size)
954 CALL create_bl_distribution(col_dist, col_blk_size, n, npcols)
956 row_dist=row_dist, col_dist=col_dist)
959 CALL dbcsr_create(matrix,
"m_n_template", dist_m_n, mysym, row_blk_size, col_blk_size)
961 DEALLOCATE (col_dist, col_blk_size)
976 SUBROUTINE create_bl_distribution(block_distribution, &
977 block_size, nelements, nbins)
978 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: block_distribution, block_size
979 INTEGER,
INTENT(IN) :: nelements, nbins
981 CHARACTER(len=*),
PARAMETER :: routinen =
'create_bl_distribution', &
982 routinep = modulen//
':'//routinen
984 INTEGER :: bin, blk_layer, element_stack, els, &
985 estimated_blocks, max_blocks_per_bin, &
987 INTEGER,
DIMENSION(:),
POINTER :: blk_dist, blk_sizes
991 NULLIFY (block_distribution)
994 IF (nelements > 0)
THEN
997 max_blocks_per_bin = ceiling(real(nblocks, kind=
dp)/real(nbins, kind=
dp))
1000 WRITE (*,
'(1X,A,1X,A,I7,A,I7,A)') routinep,
"For", nelements, &
1001 " elements and", nbins,
" bins"
1002 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1004 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1006 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1007 max_blocks_per_bin,
" max blocks/bin"
1010 estimated_blocks = max_blocks_per_bin*nbins
1011 ALLOCATE (blk_dist(estimated_blocks), stat=stat)
1015 ALLOCATE (blk_sizes(estimated_blocks), stat=stat)
1017 cpabort(
"blk_sizes")
1021 DO blk_layer = 1, max_blocks_per_bin
1022 DO bin = 0, nbins - 1
1025 element_stack = element_stack + els
1027 blk_dist(nblks) = bin
1028 blk_sizes(nblks) = els
1029 IF (debug_mod)
WRITE (*,
'(1X,A,I5,A,I5,A,I5)') routinep//
" Assigning", &
1030 els,
" elements as block", nblks,
" to bin", bin
1035 IF (nblks == estimated_blocks)
THEN
1036 block_distribution => blk_dist
1037 block_size => blk_sizes
1039 ALLOCATE (block_distribution(nblks), stat=stat)
1043 block_distribution(:) = blk_dist(1:nblks)
1044 DEALLOCATE (blk_dist)
1045 ALLOCATE (block_size(nblks), stat=stat)
1047 cpabort(
"blk_sizes")
1049 block_size(:) = blk_sizes(1:nblks)
1050 DEALLOCATE (blk_sizes)
1053 ALLOCATE (block_distribution(0), stat=stat)
1057 ALLOCATE (block_size(0), stat=stat)
1059 cpabort(
"blk_sizes")
10621579
FORMAT(i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5)
1064 WRITE (*,
'(1X,A,A)') routinep//
" Distribution"
1065 WRITE (*, 1579) block_distribution(:)
1066 WRITE (*,
'(1X,A,A)') routinep//
" Sizes"
1067 WRITE (*, 1579) block_size(:)
1069 END SUBROUTINE create_bl_distribution
1083 right_col_blk_sizes)
1086 INTEGER,
INTENT(IN) :: ncolumns
1087 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: right_col_blk_sizes
1089 INTEGER :: multiplicity, ncols, nimages, npcols, &
1091 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: tmp_images
1092 INTEGER,
DIMENSION(:),
POINTER :: old_col_dist, right_col_dist, &
1097 col_dist=old_col_dist, &
1102 CALL create_bl_distribution(right_col_dist, right_col_blk_sizes, ncolumns, npcols)
1104 ALLOCATE (right_row_dist(ncols), tmp_images(ncols))
1105 nimages =
lcm(nprows, npcols)/nprows
1106 multiplicity = nprows/
gcd(nprows, npcols)
1107 CALL rebin_distribution(right_row_dist, tmp_images, old_col_dist, nprows, multiplicity, nimages)
1110 template=dist_left, &
1111 row_dist=right_row_dist, &
1112 col_dist=right_col_dist, &
1115 reuse_arrays=.true.)
1116 DEALLOCATE (tmp_images)
1152 SUBROUTINE rebin_distribution(new_bins, images, source_bins, &
1153 nbins, multiplicity, nimages)
1154 INTEGER,
DIMENSION(:),
INTENT(OUT) :: new_bins, images
1155 INTEGER,
DIMENSION(:),
INTENT(IN) :: source_bins
1156 INTEGER,
INTENT(IN) :: nbins, multiplicity, nimages
1158 INTEGER :: bin, i, old_nbins, virtual_bin
1159 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: bin_multiplier
1163 IF (mod(nbins*nimages, multiplicity) /= 0)
THEN
1164 cpwarn(
"mulitplicity is not divisor of new process grid coordinate")
1166 old_nbins = (nbins*nimages)/multiplicity
1167 ALLOCATE (bin_multiplier(0:old_nbins - 1))
1168 bin_multiplier(:) = 0
1169 DO i = 1,
SIZE(new_bins)
1170 IF (i <=
SIZE(source_bins))
THEN
1171 bin = source_bins(i)
1174 bin = mod(i, old_nbins)
1176 virtual_bin = bin*multiplicity + bin_multiplier(bin)
1177 new_bins(i) = virtual_bin/nimages
1178 images(i) = 1 + mod(virtual_bin, nimages)
1179 bin_multiplier(bin) = bin_multiplier(bin) + 1
1180 IF (bin_multiplier(bin) >= multiplicity)
THEN
1181 bin_multiplier(bin) = 0
1184 END SUBROUTINE rebin_distribution
1201 SUBROUTINE dbcsr_create_dist_block_cyclic(dist, nrows, ncolumns, &
1202 nrow_block, ncol_block, group_handle, pgrid, row_blk_sizes, col_blk_sizes)
1204 INTEGER,
INTENT(IN) :: nrows, ncolumns, nrow_block, ncol_block, &
1206 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
1207 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: row_blk_sizes, col_blk_sizes
1209 CHARACTER(len=*),
PARAMETER :: routinen =
'dbcsr_create_dist_block_cyclic'
1211 INTEGER :: nblkcols, nblkrows, npcols, nprows, &
1213 INTEGER,
DIMENSION(:),
POINTER :: cd_data, rd_data
1216 IF (nrow_block == 0)
THEN
1220 nblkrows = nrows/nrow_block
1221 sz = mod(nrows, nrow_block)
1223 IF (sz > 0) nblkrows = nblkrows + 1
1224 ALLOCATE (row_blk_sizes(nblkrows), rd_data(nblkrows))
1225 row_blk_sizes = nrow_block
1226 IF (sz /= 0) row_blk_sizes(nblkrows) = sz
1229 IF (ncol_block == 0)
THEN
1233 nblkcols = ncolumns/ncol_block
1234 sz = mod(ncolumns, ncol_block)
1236 IF (sz > 0) nblkcols = nblkcols + 1
1237 ALLOCATE (col_blk_sizes(nblkcols), cd_data(nblkcols))
1238 col_blk_sizes = ncol_block
1239 IF (sz /= 0) col_blk_sizes(nblkcols) = sz
1242 WRITE (*, *) routinen//
" nrows,nrow_block,nblkrows=", &
1243 nrows, nrow_block, nblkrows
1244 WRITE (*, *) routinen//
" ncols,ncol_block,nblkcols=", &
1245 ncolumns, ncol_block, nblkcols
1248 nprows =
SIZE(pgrid, 1)
1249 DO pdim = 0, min(nprows - 1, nblkrows - 1)
1250 rd_data(1 + pdim:nblkrows:nprows) = pdim
1253 npcols =
SIZE(pgrid, 2)
1254 DO pdim = 0, min(npcols - 1, nblkcols - 1)
1255 cd_data(1 + pdim:nblkcols:npcols) = pdim
1259 WRITE (*, *) routinen//
" row_dist", &
1261 WRITE (*, *) routinen//
" col_dist", &
1266 group=group_handle, pgrid=pgrid, &
1269 reuse_arrays=.true.)
1271 END SUBROUTINE dbcsr_create_dist_block_cyclic
1280 SUBROUTINE allocate_dbcsr_matrix_set_1d(matrix_set, nmatrix)
1281 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_set
1282 INTEGER,
INTENT(IN) :: nmatrix
1287 ALLOCATE (matrix_set(nmatrix))
1288 DO imatrix = 1, nmatrix
1289 NULLIFY (matrix_set(imatrix)%matrix)
1291 END SUBROUTINE allocate_dbcsr_matrix_set_1d
1301 SUBROUTINE allocate_dbcsr_matrix_set_2d(matrix_set, nmatrix, mmatrix)
1302 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_set
1303 INTEGER,
INTENT(IN) :: nmatrix, mmatrix
1305 INTEGER :: imatrix, jmatrix
1308 ALLOCATE (matrix_set(nmatrix, mmatrix))
1309 DO jmatrix = 1, mmatrix
1310 DO imatrix = 1, nmatrix
1311 NULLIFY (matrix_set(imatrix, jmatrix)%matrix)
1314 END SUBROUTINE allocate_dbcsr_matrix_set_2d
1325 SUBROUTINE allocate_dbcsr_matrix_set_3d(matrix_set, nmatrix, mmatrix, pmatrix)
1326 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :),
POINTER :: matrix_set
1327 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix
1329 INTEGER :: imatrix, jmatrix, kmatrix
1332 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix))
1333 DO kmatrix = 1, pmatrix
1334 DO jmatrix = 1, mmatrix
1335 DO imatrix = 1, nmatrix
1336 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix)%matrix)
1340 END SUBROUTINE allocate_dbcsr_matrix_set_3d
1352 SUBROUTINE allocate_dbcsr_matrix_set_4d(matrix_set, nmatrix, mmatrix, pmatrix, qmatrix)
1353 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :, :),
POINTER :: matrix_set
1354 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix, qmatrix
1356 INTEGER :: imatrix, jmatrix, kmatrix, lmatrix
1359 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix, qmatrix))
1360 DO lmatrix = 1, qmatrix
1361 DO kmatrix = 1, pmatrix
1362 DO jmatrix = 1, mmatrix
1363 DO imatrix = 1, nmatrix
1364 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix, lmatrix)%matrix)
1369 END SUBROUTINE allocate_dbcsr_matrix_set_4d
1382 SUBROUTINE allocate_dbcsr_matrix_set_5d(matrix_set, nmatrix, mmatrix, pmatrix, qmatrix, smatrix)
1384 POINTER :: matrix_set
1385 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix, qmatrix, &
1388 INTEGER :: hmatrix, imatrix, jmatrix, kmatrix, &
1392 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix, qmatrix, smatrix))
1393 DO hmatrix = 1, smatrix
1394 DO lmatrix = 1, qmatrix
1395 DO kmatrix = 1, pmatrix
1396 DO jmatrix = 1, mmatrix
1397 DO imatrix = 1, nmatrix
1398 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix, lmatrix, hmatrix)%matrix)
1404 END SUBROUTINE allocate_dbcsr_matrix_set_5d
1412 SUBROUTINE deallocate_dbcsr_matrix_set_1d(matrix_set)
1414 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_set
1418 IF (
ASSOCIATED(matrix_set))
THEN
1419 DO imatrix = 1,
SIZE(matrix_set)
1422 DEALLOCATE (matrix_set)
1425 END SUBROUTINE deallocate_dbcsr_matrix_set_1d
1433 SUBROUTINE deallocate_dbcsr_matrix_set_2d(matrix_set)
1435 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_set
1437 INTEGER :: imatrix, jmatrix
1439 IF (
ASSOCIATED(matrix_set))
THEN
1440 DO jmatrix = 1,
SIZE(matrix_set, 2)
1441 DO imatrix = 1,
SIZE(matrix_set, 1)
1445 DEALLOCATE (matrix_set)
1447 END SUBROUTINE deallocate_dbcsr_matrix_set_2d
1455 SUBROUTINE deallocate_dbcsr_matrix_set_3d(matrix_set)
1457 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :),
POINTER :: matrix_set
1459 INTEGER :: imatrix, jmatrix, kmatrix
1461 IF (
ASSOCIATED(matrix_set))
THEN
1462 DO kmatrix = 1,
SIZE(matrix_set, 3)
1463 DO jmatrix = 1,
SIZE(matrix_set, 2)
1464 DO imatrix = 1,
SIZE(matrix_set, 1)
1469 DEALLOCATE (matrix_set)
1471 END SUBROUTINE deallocate_dbcsr_matrix_set_3d
1479 SUBROUTINE deallocate_dbcsr_matrix_set_4d(matrix_set)
1481 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :, :),
POINTER :: matrix_set
1483 INTEGER :: imatrix, jmatrix, kmatrix, lmatrix
1485 IF (
ASSOCIATED(matrix_set))
THEN
1486 DO lmatrix = 1,
SIZE(matrix_set, 4)
1487 DO kmatrix = 1,
SIZE(matrix_set, 3)
1488 DO jmatrix = 1,
SIZE(matrix_set, 2)
1489 DO imatrix = 1,
SIZE(matrix_set, 1)
1495 DEALLOCATE (matrix_set)
1497 END SUBROUTINE deallocate_dbcsr_matrix_set_4d
1505 SUBROUTINE deallocate_dbcsr_matrix_set_5d(matrix_set)
1508 POINTER :: matrix_set
1510 INTEGER :: hmatrix, imatrix, jmatrix, kmatrix, &
1513 IF (
ASSOCIATED(matrix_set))
THEN
1514 DO hmatrix = 1,
SIZE(matrix_set, 5)
1515 DO lmatrix = 1,
SIZE(matrix_set, 4)
1516 DO kmatrix = 1,
SIZE(matrix_set, 3)
1517 DO jmatrix = 1,
SIZE(matrix_set, 2)
1518 DO imatrix = 1,
SIZE(matrix_set, 1)
1525 DEALLOCATE (matrix_set)
1527 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)
...
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_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
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, nrow, ncol, set_zero)
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