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) &
617 CALL timeset(routinen//
'_core', timing_handle_mult)
618 CALL dbcsr_multiply(
"N",
"N", my_alpha, matrix, in, my_beta, out, &
620 CALL timestop(timing_handle_mult)
626 DEALLOCATE (col_blk_size_right_in, col_blk_size_right_out)
632 CALL timestop(timing_handle)
642 SUBROUTINE match_col_sizes(sizes1, sizes2, full_num)
643 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: sizes1
644 INTEGER,
DIMENSION(:),
INTENT(IN) :: sizes2
645 INTEGER,
INTENT(IN) :: full_num
647 INTEGER :: left, n1, n2, p, rm, used
652 cpabort(
"distributions must be equal!")
653 sizes1(1:n1) = sizes2(1:n1)
654 used = sum(sizes1(1:n1))
658 IF (used < full_num)
THEN
659 sizes1(n1) = sizes1(n1) + full_num - used
661 left = used - full_num
663 DO WHILE (left > 0 .AND. p > 0)
664 rm = min(left, sizes1(p))
665 sizes1(p) = sizes1(p) - rm
670 END SUBROUTINE match_col_sizes
691 TYPE(
dbcsr_type),
INTENT(INOUT) :: sparse_matrix
693 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_g
694 INTEGER,
INTENT(IN) :: ncol
695 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: alpha
696 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
697 INTEGER,
INTENT(IN),
OPTIONAL :: symmetry_mode
699 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_dbcsr_plus_fm_fm_t'
701 INTEGER :: k, my_symmetry_mode, nao, npcols, &
703 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size_left, col_dist_left, &
704 row_blk_size, row_dist
705 LOGICAL :: check_product, my_keep_sparsity
706 REAL(kind=
dp) :: my_alpha, norm
710 TYPE(
dbcsr_type) :: mat_g, mat_v, sparse_matrix2, &
713 check_product = .false.
715 CALL timeset(routinen, timing_handle)
717 my_keep_sparsity = .true.
718 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
721 IF (
PRESENT(symmetry_mode)) my_symmetry_mode = symmetry_mode
723 NULLIFY (col_dist_left)
727 cpabort(
"sparse_matrix must pre-exist")
734 CALL create_bl_distribution(col_dist_left, col_blk_size_left, k, npcols)
736 row_dist=row_dist, col_dist=col_dist_left)
737 DEALLOCATE (col_dist_left)
739 CALL dbcsr_create(mat_v,
"DBCSR matrix_v", dist_left, dbcsr_type_no_symmetry, &
740 row_blk_size, col_blk_size_left)
745 IF (
PRESENT(matrix_g))
THEN
746 CALL dbcsr_create(mat_g,
"DBCSR matrix_g", dist_left, dbcsr_type_no_symmetry, &
747 row_blk_size, col_blk_size_left)
751 DEALLOCATE (col_blk_size_left)
755 IF (check_product)
THEN
757 CALL cp_fm_struct_create(fm_struct_tmp, context=matrix_v%matrix_struct%context, nrow_global=nao, &
758 ncol_global=nao, para_env=matrix_v%matrix_struct%para_env)
759 CALL cp_fm_create(fm_matrix, fm_struct_tmp, name=
"fm matrix")
762 CALL dbcsr_copy(sparse_matrix3, sparse_matrix)
766 IF (
PRESENT(alpha)) my_alpha = alpha
767 IF (
PRESENT(matrix_g))
THEN
768 IF (my_symmetry_mode == 1)
THEN
771 1.0_dp, sparse_matrix, &
772 retain_sparsity=my_keep_sparsity, &
775 1.0_dp, sparse_matrix, &
776 retain_sparsity=my_keep_sparsity, &
778 ELSE IF (my_symmetry_mode == -1)
THEN
781 1.0_dp, sparse_matrix, &
782 retain_sparsity=my_keep_sparsity, &
785 1.0_dp, sparse_matrix, &
786 retain_sparsity=my_keep_sparsity, &
791 1.0_dp, sparse_matrix, &
792 retain_sparsity=my_keep_sparsity, &
797 1.0_dp, sparse_matrix, &
798 retain_sparsity=my_keep_sparsity, &
802 IF (check_product)
THEN
803 IF (
PRESENT(matrix_g))
THEN
804 IF (my_symmetry_mode == 1)
THEN
805 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_v, matrix_g, &
807 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_g, matrix_v, &
809 ELSE IF (my_symmetry_mode == -1)
THEN
810 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_v, matrix_g, &
812 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, -0.5_dp*my_alpha, matrix_g, matrix_v, &
815 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, my_alpha, matrix_v, matrix_g, &
819 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, my_alpha, matrix_v, matrix_v, &
823 CALL dbcsr_copy(sparse_matrix2, sparse_matrix)
824 CALL dbcsr_scale(sparse_matrix2, alpha_scalar=0.0_dp)
825 CALL copy_fm_to_dbcsr(fm_matrix, sparse_matrix2, keep_sparsity=my_keep_sparsity)
826 CALL dbcsr_add(sparse_matrix2, sparse_matrix, alpha_scalar=1.0_dp, &
829 WRITE (*, *)
'nao=', nao,
' k=', k,
' ncol=', ncol,
' my_alpha=', my_alpha
830 WRITE (*, *)
'PRESENT (matrix_g)',
PRESENT(matrix_g)
832 WRITE (*, *)
'norm(sm+alpha*v*g^t - fm+alpha*v*g^t)/n=', norm/real(nao,
dp)
833 IF (norm/real(nao,
dp) > 1e-12_dp)
THEN
859 CALL timestop(timing_handle)
879 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size_right_in, row_blk_size
887 CALL dbcsr_create(matrix,
"D", dist_right_in, dbcsr_type_no_symmetry, &
888 row_blk_size, col_blk_size_right_in)
891 DEALLOCATE (col_blk_size_right_in)
908 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix, template
909 INTEGER,
INTENT(IN) :: m, n
910 CHARACTER,
INTENT(IN),
OPTIONAL :: sym
913 INTEGER :: npcols, nprows
914 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_dist, row_blk_size, &
918 CALL dbcsr_get_info(template, matrix_type=mysym, distribution=tmpl_dist)
920 IF (
PRESENT(sym)) mysym = sym
922 NULLIFY (row_dist, col_dist)
923 NULLIFY (row_blk_size, col_blk_size)
927 CALL create_bl_distribution(row_dist, row_blk_size, m, nprows)
928 CALL create_bl_distribution(col_dist, col_blk_size, n, npcols)
930 row_dist=row_dist, col_dist=col_dist, &
934 CALL dbcsr_create(matrix,
"m_n_template", dist_m_n, mysym, &
935 row_blk_size, col_blk_size, reuse_arrays=.true.)
951 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix, template
953 CHARACTER,
OPTIONAL :: sym
957 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_dist, row_blk_size, &
962 IF (
PRESENT(sym)) mysym = sym
969 NULLIFY (col_dist, col_blk_size)
970 CALL create_bl_distribution(col_dist, col_blk_size, n, npcols)
972 row_dist=row_dist, col_dist=col_dist)
975 CALL dbcsr_create(matrix,
"m_n_template", dist_m_n, mysym, row_blk_size, col_blk_size)
977 DEALLOCATE (col_dist, col_blk_size)
992 SUBROUTINE create_bl_distribution(block_distribution, &
993 block_size, nelements, nbins)
994 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: block_distribution, block_size
995 INTEGER,
INTENT(IN) :: nelements, nbins
997 CHARACTER(len=*),
PARAMETER :: routinen =
'create_bl_distribution', &
998 routinep = modulen//
':'//routinen
1000 INTEGER :: bin, blk_layer, element_stack, els, &
1001 estimated_blocks, max_blocks_per_bin, &
1002 nblks, nblocks, stat
1003 INTEGER,
DIMENSION(:),
POINTER :: blk_dist, blk_sizes
1007 NULLIFY (block_distribution)
1008 NULLIFY (block_size)
1010 IF (nelements > 0)
THEN
1013 max_blocks_per_bin = ceiling(real(nblocks, kind=
dp)/real(nbins, kind=
dp))
1016 WRITE (*,
'(1X,A,1X,A,I7,A,I7,A)') routinep,
"For", nelements, &
1017 " elements and", nbins,
" bins"
1018 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1020 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1022 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1023 max_blocks_per_bin,
" max blocks/bin"
1026 estimated_blocks = max_blocks_per_bin*nbins
1027 ALLOCATE (blk_dist(estimated_blocks), stat=stat)
1030 ALLOCATE (blk_sizes(estimated_blocks), stat=stat)
1032 cpabort(
"blk_sizes")
1035 DO blk_layer = 1, max_blocks_per_bin
1036 DO bin = 0, nbins - 1
1039 element_stack = element_stack + els
1041 blk_dist(nblks) = bin
1042 blk_sizes(nblks) = els
1043 IF (debug_mod)
WRITE (*,
'(1X,A,I5,A,I5,A,I5)') routinep//
" Assigning", &
1044 els,
" elements as block", nblks,
" to bin", bin
1049 IF (nblks == estimated_blocks)
THEN
1050 block_distribution => blk_dist
1051 block_size => blk_sizes
1053 ALLOCATE (block_distribution(nblks), stat=stat)
1056 block_distribution(:) = blk_dist(1:nblks)
1057 DEALLOCATE (blk_dist)
1058 ALLOCATE (block_size(nblks), stat=stat)
1060 cpabort(
"blk_sizes")
1061 block_size(:) = blk_sizes(1:nblks)
1062 DEALLOCATE (blk_sizes)
1065 ALLOCATE (block_distribution(0), stat=stat)
1068 ALLOCATE (block_size(0), stat=stat)
1070 cpabort(
"blk_sizes")
10721579
FORMAT(i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5)
1074 WRITE (*,
'(1X,A,A)') routinep//
" Distribution"
1075 WRITE (*, 1579) block_distribution(:)
1076 WRITE (*,
'(1X,A,A)') routinep//
" Sizes"
1077 WRITE (*, 1579) block_size(:)
1079 END SUBROUTINE create_bl_distribution
1093 right_col_blk_sizes)
1096 INTEGER,
INTENT(IN) :: ncolumns
1097 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: right_col_blk_sizes
1099 INTEGER :: multiplicity, ncols, nimages, npcols, &
1101 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: tmp_images
1102 INTEGER,
DIMENSION(:),
POINTER :: old_col_dist, right_col_dist, &
1107 col_dist=old_col_dist, &
1112 CALL create_bl_distribution(right_col_dist, right_col_blk_sizes, ncolumns, npcols)
1114 ALLOCATE (right_row_dist(ncols), tmp_images(ncols))
1115 nimages =
lcm(nprows, npcols)/nprows
1116 multiplicity = nprows/
gcd(nprows, npcols)
1117 CALL rebin_distribution(right_row_dist, tmp_images, old_col_dist, nprows, multiplicity, nimages)
1120 template=dist_left, &
1121 row_dist=right_row_dist, &
1122 col_dist=right_col_dist, &
1125 reuse_arrays=.true.)
1126 DEALLOCATE (tmp_images)
1162 SUBROUTINE rebin_distribution(new_bins, images, source_bins, &
1163 nbins, multiplicity, nimages)
1164 INTEGER,
DIMENSION(:),
INTENT(OUT) :: new_bins, images
1165 INTEGER,
DIMENSION(:),
INTENT(IN) :: source_bins
1166 INTEGER,
INTENT(IN) :: nbins, multiplicity, nimages
1168 INTEGER :: bin, i, old_nbins, virtual_bin
1169 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: bin_multiplier
1173 IF (mod(nbins*nimages, multiplicity) /= 0)
THEN
1174 cpwarn(
"mulitplicity is not divisor of new process grid coordinate")
1176 old_nbins = (nbins*nimages)/multiplicity
1177 ALLOCATE (bin_multiplier(0:old_nbins - 1))
1178 bin_multiplier(:) = 0
1179 DO i = 1,
SIZE(new_bins)
1180 IF (i <=
SIZE(source_bins))
THEN
1181 bin = source_bins(i)
1184 bin = mod(i, old_nbins)
1186 virtual_bin = bin*multiplicity + bin_multiplier(bin)
1187 new_bins(i) = virtual_bin/nimages
1188 images(i) = 1 + mod(virtual_bin, nimages)
1189 bin_multiplier(bin) = bin_multiplier(bin) + 1
1190 IF (bin_multiplier(bin) >= multiplicity)
THEN
1191 bin_multiplier(bin) = 0
1194 END SUBROUTINE rebin_distribution
1211 SUBROUTINE dbcsr_create_dist_block_cyclic(dist, nrows, ncolumns, &
1212 nrow_block, ncol_block, group_handle, pgrid, row_blk_sizes, col_blk_sizes)
1214 INTEGER,
INTENT(IN) :: nrows, ncolumns, nrow_block, ncol_block, &
1216 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
1217 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: row_blk_sizes, col_blk_sizes
1219 CHARACTER(len=*),
PARAMETER :: routinen =
'dbcsr_create_dist_block_cyclic'
1221 INTEGER :: nblkcols, nblkrows, npcols, nprows, &
1223 INTEGER,
DIMENSION(:),
POINTER :: cd_data, rd_data
1226 IF (nrow_block == 0)
THEN
1230 nblkrows = nrows/nrow_block
1231 sz = mod(nrows, nrow_block)
1233 IF (sz > 0) nblkrows = nblkrows + 1
1234 ALLOCATE (row_blk_sizes(nblkrows), rd_data(nblkrows))
1235 row_blk_sizes = nrow_block
1236 IF (sz /= 0) row_blk_sizes(nblkrows) = sz
1239 IF (ncol_block == 0)
THEN
1243 nblkcols = ncolumns/ncol_block
1244 sz = mod(ncolumns, ncol_block)
1246 IF (sz > 0) nblkcols = nblkcols + 1
1247 ALLOCATE (col_blk_sizes(nblkcols), cd_data(nblkcols))
1248 col_blk_sizes = ncol_block
1249 IF (sz /= 0) col_blk_sizes(nblkcols) = sz
1252 WRITE (*, *) routinen//
" nrows,nrow_block,nblkrows=", &
1253 nrows, nrow_block, nblkrows
1254 WRITE (*, *) routinen//
" ncols,ncol_block,nblkcols=", &
1255 ncolumns, ncol_block, nblkcols
1258 nprows =
SIZE(pgrid, 1)
1259 DO pdim = 0, min(nprows - 1, nblkrows - 1)
1260 rd_data(1 + pdim:nblkrows:nprows) = pdim
1263 npcols =
SIZE(pgrid, 2)
1264 DO pdim = 0, min(npcols - 1, nblkcols - 1)
1265 cd_data(1 + pdim:nblkcols:npcols) = pdim
1269 WRITE (*, *) routinen//
" row_dist", &
1271 WRITE (*, *) routinen//
" col_dist", &
1276 group=group_handle, pgrid=pgrid, &
1279 reuse_arrays=.true.)
1281 END SUBROUTINE dbcsr_create_dist_block_cyclic
1290 SUBROUTINE allocate_dbcsr_matrix_set_1d(matrix_set, nmatrix)
1291 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_set
1292 INTEGER,
INTENT(IN) :: nmatrix
1297 ALLOCATE (matrix_set(nmatrix))
1298 DO imatrix = 1, nmatrix
1299 NULLIFY (matrix_set(imatrix)%matrix)
1301 END SUBROUTINE allocate_dbcsr_matrix_set_1d
1311 SUBROUTINE allocate_dbcsr_matrix_set_2d(matrix_set, nmatrix, mmatrix)
1312 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_set
1313 INTEGER,
INTENT(IN) :: nmatrix, mmatrix
1315 INTEGER :: imatrix, jmatrix
1318 ALLOCATE (matrix_set(nmatrix, mmatrix))
1319 DO jmatrix = 1, mmatrix
1320 DO imatrix = 1, nmatrix
1321 NULLIFY (matrix_set(imatrix, jmatrix)%matrix)
1324 END SUBROUTINE allocate_dbcsr_matrix_set_2d
1335 SUBROUTINE allocate_dbcsr_matrix_set_3d(matrix_set, nmatrix, mmatrix, pmatrix)
1336 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :),
POINTER :: matrix_set
1337 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix
1339 INTEGER :: imatrix, jmatrix, kmatrix
1342 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix))
1343 DO kmatrix = 1, pmatrix
1344 DO jmatrix = 1, mmatrix
1345 DO imatrix = 1, nmatrix
1346 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix)%matrix)
1350 END SUBROUTINE allocate_dbcsr_matrix_set_3d
1362 SUBROUTINE allocate_dbcsr_matrix_set_4d(matrix_set, nmatrix, mmatrix, pmatrix, qmatrix)
1363 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :, :),
POINTER :: matrix_set
1364 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix, qmatrix
1366 INTEGER :: imatrix, jmatrix, kmatrix, lmatrix
1369 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix, qmatrix))
1370 DO lmatrix = 1, qmatrix
1371 DO kmatrix = 1, pmatrix
1372 DO jmatrix = 1, mmatrix
1373 DO imatrix = 1, nmatrix
1374 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix, lmatrix)%matrix)
1379 END SUBROUTINE allocate_dbcsr_matrix_set_4d
1392 SUBROUTINE allocate_dbcsr_matrix_set_5d(matrix_set, nmatrix, mmatrix, pmatrix, qmatrix, smatrix)
1394 POINTER :: matrix_set
1395 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix, qmatrix, &
1398 INTEGER :: hmatrix, imatrix, jmatrix, kmatrix, &
1402 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix, qmatrix, smatrix))
1403 DO hmatrix = 1, smatrix
1404 DO lmatrix = 1, qmatrix
1405 DO kmatrix = 1, pmatrix
1406 DO jmatrix = 1, mmatrix
1407 DO imatrix = 1, nmatrix
1408 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix, lmatrix, hmatrix)%matrix)
1414 END SUBROUTINE allocate_dbcsr_matrix_set_5d
1422 SUBROUTINE deallocate_dbcsr_matrix_set_1d(matrix_set)
1424 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_set
1428 IF (
ASSOCIATED(matrix_set))
THEN
1429 DO imatrix = 1,
SIZE(matrix_set)
1432 DEALLOCATE (matrix_set)
1435 END SUBROUTINE deallocate_dbcsr_matrix_set_1d
1443 SUBROUTINE deallocate_dbcsr_matrix_set_2d(matrix_set)
1445 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_set
1447 INTEGER :: imatrix, jmatrix
1449 IF (
ASSOCIATED(matrix_set))
THEN
1450 DO jmatrix = 1,
SIZE(matrix_set, 2)
1451 DO imatrix = 1,
SIZE(matrix_set, 1)
1455 DEALLOCATE (matrix_set)
1457 END SUBROUTINE deallocate_dbcsr_matrix_set_2d
1465 SUBROUTINE deallocate_dbcsr_matrix_set_3d(matrix_set)
1467 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :),
POINTER :: matrix_set
1469 INTEGER :: imatrix, jmatrix, kmatrix
1471 IF (
ASSOCIATED(matrix_set))
THEN
1472 DO kmatrix = 1,
SIZE(matrix_set, 3)
1473 DO jmatrix = 1,
SIZE(matrix_set, 2)
1474 DO imatrix = 1,
SIZE(matrix_set, 1)
1479 DEALLOCATE (matrix_set)
1481 END SUBROUTINE deallocate_dbcsr_matrix_set_3d
1489 SUBROUTINE deallocate_dbcsr_matrix_set_4d(matrix_set)
1491 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :, :),
POINTER :: matrix_set
1493 INTEGER :: imatrix, jmatrix, kmatrix, lmatrix
1495 IF (
ASSOCIATED(matrix_set))
THEN
1496 DO lmatrix = 1,
SIZE(matrix_set, 4)
1497 DO kmatrix = 1,
SIZE(matrix_set, 3)
1498 DO jmatrix = 1,
SIZE(matrix_set, 2)
1499 DO imatrix = 1,
SIZE(matrix_set, 1)
1505 DEALLOCATE (matrix_set)
1507 END SUBROUTINE deallocate_dbcsr_matrix_set_4d
1515 SUBROUTINE deallocate_dbcsr_matrix_set_5d(matrix_set)
1518 POINTER :: matrix_set
1520 INTEGER :: hmatrix, imatrix, jmatrix, kmatrix, &
1523 IF (
ASSOCIATED(matrix_set))
THEN
1524 DO hmatrix = 1,
SIZE(matrix_set, 5)
1525 DO lmatrix = 1,
SIZE(matrix_set, 4)
1526 DO kmatrix = 1,
SIZE(matrix_set, 3)
1527 DO jmatrix = 1,
SIZE(matrix_set, 2)
1528 DO imatrix = 1,
SIZE(matrix_set, 1)
1535 DEALLOCATE (matrix_set)
1537 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