50#include "base/base_uses.f90"
55 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_dbcsr_operations'
56 LOGICAL,
PARAMETER :: debug_mod = .false.
64 TYPE dbcsr_fm_thread_plan_type
65 INTEGER,
ALLOCATABLE :: blocks(:, :), slots(:)
66 END TYPE dbcsr_fm_thread_plan_type
70 TYPE(cp_fm_struct_type),
POINTER :: matrix_struct => null()
71 CHARACTER :: matrix_type =
" "
72 TYPE(dbcsr_fm_thread_plan_type),
ALLOCATABLE :: thread(:)
73 INTEGER,
ALLOCATABLE :: send_count(:), send_disp(:), recv_count(:), recv_disp(:), recv_index(:, :)
74 REAL(kind=
dp),
ALLOCATABLE :: send_values(:), recv_values(:)
97 MODULE PROCEDURE allocate_dbcsr_matrix_set_1d
98 MODULE PROCEDURE allocate_dbcsr_matrix_set_2d
99 MODULE PROCEDURE allocate_dbcsr_matrix_set_3d
100 MODULE PROCEDURE allocate_dbcsr_matrix_set_4d
101 MODULE PROCEDURE allocate_dbcsr_matrix_set_5d
105 MODULE PROCEDURE deallocate_dbcsr_matrix_set_1d
106 MODULE PROCEDURE deallocate_dbcsr_matrix_set_2d
107 MODULE PROCEDURE deallocate_dbcsr_matrix_set_3d
108 MODULE PROCEDURE deallocate_dbcsr_matrix_set_4d
109 MODULE PROCEDURE deallocate_dbcsr_matrix_set_5d
122 TYPE(
dbcsr_p_type),
INTENT(IN) :: matrix_c(:), matrix_a(:, :)
123 REAL(
dp),
INTENT(IN) :: alpha(:)
126 REAL(
dp),
ALLOCATABLE ::
value(:, :), buffer(:, :)
127 END TYPE local_sum_type
129 INTEGER :: first, i, j, k, n, nbatch, nworkers
130 TYPE(local_sum_type),
ALLOCATABLE :: work(:)
132 cpassert(
SIZE(matrix_c) ==
SIZE(matrix_a, 1))
133 cpassert(
SIZE(alpha) ==
SIZE(matrix_a, 2))
134 IF (
SIZE(matrix_c) == 0)
RETURN
137 ALLOCATE (work(nworkers))
138 DO first = 1,
SIZE(matrix_c), nworkers
139 nbatch = min(nworkers,
SIZE(matrix_c) - first + 1)
141 CALL dbcsr_get_info(matrix_c(first + j - 1)%matrix, nfullrows_total=n, nfullcols_total=k)
142 IF (
ALLOCATED(work(j)%value))
THEN
143 IF (
SIZE(work(j)%value, 1) /= n .OR.
SIZE(work(j)%value, 2) /= k)
THEN
144 DEALLOCATE (work(j)%value, work(j)%buffer)
147 IF (.NOT.
ALLOCATED(work(j)%value))
ALLOCATE (work(j)%value(n, k), work(j)%buffer(n, k))
148 work(j)%value(:, :) = 0.0_dp
150 DO i = 1,
SIZE(alpha)
156 work(j)%value(:, :) = work(j)%value(:, :) + alpha(i)*work(j)%buffer(:, :)
173 REAL(
dp),
INTENT(OUT) :: dense(:, :)
175 INTEGER :: col, nc, nr, row
176 LOGICAL :: transposed
177 REAL(
dp),
POINTER :: block(:, :)
185 row_size=nr, col_size=nc, row_offset=row, col_offset=col)
187 dense(row:row + nr - 1, col:col + nc - 1) = transpose(block)
189 dense(row:row + nr - 1, col:col + nc - 1) = block
202 REAL(
dp),
INTENT(IN) :: dense(:, :)
204 INTEGER :: col, nc, nr, row
205 LOGICAL :: transposed
206 REAL(
dp),
POINTER :: block(:, :)
214 row_size=nr, col_size=nc, row_offset=row, col_offset=col)
216 block(:, :) = transpose(dense(row:row + nr - 1, col:col + nc - 1))
218 block(:, :) = dense(row:row + nr - 1, col:col + nc - 1)
242 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
244 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_fm_to_dbcsr'
247 LOGICAL :: my_keep_sparsity
250 CALL timeset(routinen, handle)
252 my_keep_sparsity = .false.
253 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
257 IF (my_keep_sparsity)
THEN
260 CALL dbcsr_copy(matrix, redist_mat, keep_sparsity=.true.)
268 CALL timestop(handle)
281 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_fm_to_dbcsr_bc'
283 INTEGER :: col, handle, ncol_block, ncol_global, &
284 nrow_block, nrow_global, row
285 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: first_col, first_row, last_col, last_row
286 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, row_blk_size
287 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
288 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: dbcsr_block, fm_block
292 CALL timeset(routinen, handle)
295 pgrid => fm%matrix_struct%context%blacs2mpi
298 nrow_block = fm%matrix_struct%nrow_block
299 ncol_block = fm%matrix_struct%ncol_block
300 nrow_global = fm%matrix_struct%nrow_global
301 ncol_global = fm%matrix_struct%ncol_global
302 NULLIFY (col_blk_size, row_blk_size)
303 CALL dbcsr_create_dist_block_cyclic(bc_dist, &
304 nrows=nrow_global, ncolumns=ncol_global, &
305 nrow_block=nrow_block, ncol_block=ncol_block, &
306 group_handle=fm%matrix_struct%para_env%get_handle(), pgrid=pgrid, &
307 row_blk_sizes=row_blk_size, col_blk_sizes=col_blk_size)
311 dbcsr_type_no_symmetry, row_blk_size, col_blk_size, reuse_arrays=.true.)
317 CALL calculate_fm_block_ranges(bc_mat, first_row, last_row, first_col, last_col)
321 fm_block => fm%local_data
327 dbcsr_block(:, :) = fm_block(first_row(row):last_row(row), first_col(col):last_col(col))
332 CALL timestop(handle)
348 LOGICAL,
INTENT(IN),
OPTIONAL :: check_plan
350 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_dbcsr_to_fm'
352 CHARACTER(len=default_string_length) :: name
353 INTEGER :: group_handle, handle, ncol_block, &
354 nfullcols_total, nfullrows_total, &
356 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, row_blk_size
357 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
358 LOGICAL :: validate_plan
363 CALL timeset(routinen, handle)
364 validate_plan = .false.
365 IF (
PRESENT(check_plan)) validate_plan = check_plan
371 nfullrows_total=nfullrows_total, &
372 nfullcols_total=nfullcols_total)
374 cpassert(fm%matrix_struct%nrow_global == nfullrows_total)
375 cpassert(fm%matrix_struct%ncol_global == nfullcols_total)
378 CASE (dbcsr_type_symmetric, dbcsr_type_antisymmetric)
379 IF (
PRESENT(plan))
THEN
380 CALL copy_dbcsr_to_fm_sym(matrix, fm, plan, validate_plan)
382 CALL copy_dbcsr_to_fm_sym(matrix, fm, local_plan, .false.)
384 CALL timestop(handle)
392 nrow_block = fm%matrix_struct%nrow_block
393 ncol_block = fm%matrix_struct%ncol_block
396 NULLIFY (col_blk_size, row_blk_size)
398 CALL dbcsr_create_dist_block_cyclic(bc_dist, &
399 nrows=nfullrows_total, ncolumns=nfullcols_total, &
400 nrow_block=nrow_block, ncol_block=ncol_block, &
401 group_handle=group_handle, pgrid=pgrid, &
402 row_blk_sizes=row_blk_size, col_blk_sizes=col_blk_size)
404 CALL dbcsr_create(bc_mat,
"Block-cyclic"//name, bc_dist, &
405 dbcsr_type_no_symmetry, row_blk_size, col_blk_size, reuse_arrays=.true.)
411 CALL dbcsr_create(matrix_nosym, template=matrix, matrix_type=dbcsr_type_no_symmetry)
421 CALL timestop(handle)
432 SUBROUTINE copy_dbcsr_to_fm_sym(matrix, fm, plan, check_plan)
436 LOGICAL,
INTENT(IN) :: check_plan
438 INTEGER :: attempt, col, col_offset, i, iblock, j, &
439 k, mirror, ncol, nrecv, nrow, &
440 nthreads, pos, rebuild, row, &
442 LOGICAL :: block_matches, layout_matches, transposed
443 REAL(kind=
dp) :: symmetry_sign,
value
444 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: block
448 IF (.NOT.
ALLOCATED(plan%thread))
CALL dbcsr_to_fm_plan_create(matrix, fm, plan)
449 para_env => fm%matrix_struct%context%para_env
450 symmetry_sign = 1.0_dp
454 layout_matches =
ASSOCIATED(plan%matrix_struct, fm%matrix_struct) .AND. &
464 IF (.NOT. layout_matches .OR. nthreads /=
SIZE(plan%thread))
THEN
472 row_size=nrow, col_size=ncol, row_offset=row_offset, col_offset=col_offset)
474 block_matches = iblock <=
SIZE(plan%thread(thread)%blocks, 2)
475 IF (block_matches) block_matches = all(plan%thread(thread)%blocks(:, iblock) == &
476 [row, col, nrow, ncol, row_offset, col_offset])
477 IF (.NOT. block_matches)
THEN
484 value = symmetry_sign*block(j, i)
489 IF (mirror == 2 .AND. row == col) cycle
491 k = plan%thread(thread)%slots(pos)
492 plan%send_values(k) =
value
493 value = symmetry_sign*
value
499 IF (iblock /=
SIZE(plan%thread(thread)%blocks, 2) .OR. &
500 pos /=
SIZE(plan%thread(thread)%slots)) rebuild = 1
503 IF (check_plan)
CALL para_env%max(rebuild)
504 IF (rebuild == 0)
EXIT
505 cpassert(check_plan .AND. attempt == 1)
506 CALL dbcsr_to_fm_plan_create(matrix, fm, plan)
510 CALL para_env%alltoall(plan%send_values, plan%send_count, plan%send_disp, &
511 plan%recv_values, plan%recv_count, plan%recv_disp)
512 nrecv = sum(plan%recv_count)
513 fm%local_data = 0.0_dp
516 fm%local_data(plan%recv_index(1, k), plan%recv_index(2, k)) = plan%recv_values(k)
520 END SUBROUTINE copy_dbcsr_to_fm_sym
530 SUBROUTINE dbcsr_to_fm_plan_create(matrix, fm, plan)
535 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_to_fm_plan_create'
537 INTEGER :: col, col_offset, dest, handle, i, &
538 iblock, j, k, mirror, ncol, nproc, &
539 nrow, nthreads, pass, pos, row, &
540 row_offset, thread, x, y
541 INTEGER(KIND=int_8) :: count, offset
542 INTEGER(KIND=int_8),
ALLOCATABLE,
DIMENSION(:) :: local_pos
543 INTEGER(KIND=int_8),
ALLOCATABLE,
DIMENSION(:, :) :: thread_pos
544 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: nblocks
545 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: send_index
546 LOGICAL :: transposed
551 CALL timeset(routinen, handle)
552 fms => fm%matrix_struct
553 plan%matrix_struct => fms
555 para_env => fms%context%para_env
556 nproc = para_env%num_pe
559 ALLOCATE (thread_pos(0:nproc - 1, 0:nthreads - 1), nblocks(0:nthreads - 1))
560 ALLOCATE (plan%send_count(0:nproc - 1), plan%send_disp(0:nproc - 1), &
561 plan%recv_count(0:nproc - 1), plan%recv_disp(0:nproc - 1))
572 ALLOCATE (local_pos(0:nproc - 1))
579 cpassert(sum(thread_pos) <= int(huge(0),
int_8)/2)
580 plan%send_count(:) = int(sum(thread_pos, dim=2))
582 ALLOCATE (plan%thread(0:nthreads - 1))
583 DO k = 0, nthreads - 1
584 ALLOCATE (plan%thread(k)%blocks(6, nblocks(k)), &
585 plan%thread(k)%slots(int(sum(thread_pos(:, k)))))
588 DO dest = 0, nproc - 1
589 plan%send_disp(dest) = int(offset)
590 DO k = 0, nthreads - 1
591 count = thread_pos(dest, k)
592 thread_pos(dest, k) = offset
593 offset = offset + count
596 ALLOCATE (send_index(2, max(1, sum(plan%send_count))), &
597 plan%send_values(max(1, sum(plan%send_count))))
599 plan%send_values(:) = 0.0_dp
601 local_pos(:) = thread_pos(:, thread)
606 row_offset=row_offset, col_offset=col_offset, transposed=transposed)
609 plan%thread(thread)%blocks(:, iblock) = [row, col, nrow, ncol, row_offset, col_offset]
614 IF (mirror == 2 .AND. row == col) cycle
615 x = row_offset + i - 1
616 y = col_offset + j - 1
617 IF (mirror == 2)
THEN
618 x = col_offset + j - 1
619 y = row_offset + i - 1
621 dest = fms%context%blacs2mpi(fms%g2p_row(x), fms%g2p_col(y))
622 local_pos(dest) = local_pos(dest) + 1
624 k = int(local_pos(dest))
625 send_index(:, k) = [fms%g2l_row(x), fms%g2l_col(y)]
627 plan%thread(thread)%slots(pos) = k
634 thread_pos(:, thread) = local_pos(:)
635 nblocks(thread) = iblock
639 DEALLOCATE (local_pos)
641 DEALLOCATE (thread_pos, nblocks)
643 CALL para_env%alltoall(plan%send_count, plan%recv_count, 1)
644 cpassert(sum(int(plan%recv_count,
int_8)) <= int(huge(0),
int_8)/2)
645 plan%recv_disp(0) = 0
646 DO dest = 1, nproc - 1
647 plan%recv_disp(dest) = plan%recv_disp(dest - 1) + plan%recv_count(dest - 1)
649 ALLOCATE (plan%recv_index(2, max(1, sum(plan%recv_count))), &
650 plan%recv_values(max(1, sum(plan%recv_count))))
651 plan%recv_index(:, :) = 0
652 plan%recv_values(:) = 0.0_dp
653 CALL para_env%alltoall(send_index, 2*plan%send_count, 2*plan%send_disp, &
654 plan%recv_index, 2*plan%recv_count, 2*plan%recv_disp)
655 CALL timestop(handle)
657 END SUBROUTINE dbcsr_to_fm_plan_create
668 CHARACTER(LEN=*),
PARAMETER :: routinen =
'copy_dbcsr_to_fm_bc'
670 INTEGER :: col, handle, row
671 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: first_col, first_row, last_col, last_row
672 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: dbcsr_block, fm_block
675 CALL timeset(routinen, handle)
677 CALL calculate_fm_block_ranges(bc_mat, first_row, last_row, first_col, last_col)
680 fm_block => fm%local_data
681 fm_block = real(0.0, kind=
dp)
687 fm_block(first_row(row):last_row(row), first_col(col):last_col(col)) = dbcsr_block(:, :)
692 CALL timestop(handle)
704 SUBROUTINE calculate_fm_block_ranges(bc_mat, first_row, last_row, first_col, last_col)
706 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: first_row, last_row, first_col, last_col
708 INTEGER :: col, nblkcols_local, nblkcols_total, &
709 nblkrows_local, nblkrows_total, row
710 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: local_col_sizes, local_row_sizes
711 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, local_cols, local_rows, &
715 nblkrows_total=nblkrows_total, &
716 nblkcols_total=nblkcols_total, &
717 nblkrows_local=nblkrows_local, &
718 nblkcols_local=nblkcols_local, &
719 local_rows=local_rows, &
720 local_cols=local_cols, &
721 row_blk_size=row_blk_size, &
722 col_blk_size=col_blk_size)
725 ALLOCATE (local_row_sizes(nblkrows_total))
726 local_row_sizes(:) = 0
727 IF (nblkrows_local >= 1)
THEN
728 DO row = 1, nblkrows_local
729 local_row_sizes(local_rows(row)) = row_blk_size(local_rows(row))
732 ALLOCATE (first_row(nblkrows_total), last_row(nblkrows_total))
733 CALL dbcsr_convert_sizes_to_offsets(local_row_sizes, first_row, last_row)
734 DEALLOCATE (local_row_sizes)
737 ALLOCATE (local_col_sizes(nblkcols_total))
738 local_col_sizes(:) = 0
739 IF (nblkcols_local >= 1)
THEN
740 DO col = 1, nblkcols_local
741 local_col_sizes(local_cols(col)) = col_blk_size(local_cols(col))
744 ALLOCATE (first_col(nblkcols_total), last_col(nblkcols_total))
745 CALL dbcsr_convert_sizes_to_offsets(local_col_sizes, first_col, last_col)
746 DEALLOCATE (local_col_sizes)
748 END SUBROUTINE calculate_fm_block_ranges
762 ncol, source_start, target_start, para_env, blacs_env)
766 INTEGER,
INTENT(IN) :: ncol, source_start, target_start
770 INTEGER :: nfullcols_total, nfullrows_total
775 CALL dbcsr_get_info(matrix_a, nfullrows_total=nfullrows_total, nfullcols_total=nfullcols_total)
777 ncol_global=nfullcols_total, para_env=para_env)
778 CALL cp_fm_create(fm_matrix_a, fm_struct, name=
"fm_matrix_a")
781 CALL dbcsr_get_info(matrix_b, nfullrows_total=nfullrows_total, nfullcols_total=nfullcols_total)
783 ncol_global=nfullcols_total, para_env=para_env)
784 CALL cp_fm_create(fm_matrix_b, fm_struct, name=
"fm_matrix_b")
790 CALL cp_fm_to_fm(fm_matrix_a, fm_matrix_b, ncol, source_start, target_start)
810 INTEGER,
DIMENSION(:),
POINTER :: col_dist, row_dist
811 INTEGER,
DIMENSION(:, :),
POINTER :: col_dist_data, pgrid, row_dist_data
818 row_distribution=row_dist_data, &
819 col_distribution=col_dist_data, &
821 CALL blacs_env%get(para_env=para_env, blacs2mpi=pgrid)
824 row_dist => row_dist_data(:, 1)
825 col_dist => col_dist_data(:, 1)
830 group=para_env%get_handle(), pgrid=pgrid, &
848 REAL(
dp),
DIMENSION(:, :),
INTENT(IN) :: vec_b
849 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT) :: vec_c
850 INTEGER,
INTENT(in),
OPTIONAL :: ncol
851 REAL(
dp),
INTENT(IN),
OPTIONAL :: alpha
853 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_multiply_local'
855 INTEGER :: col, coloff, my_ncol, row, rowoff, &
858 REAL(
dp) :: my_alpha, my_alpha2
859 REAL(
dp),
DIMENSION(:, :),
POINTER :: data_d
862 CALL timeset(routinen, timing_handle)
865 IF (
PRESENT(alpha)) my_alpha = alpha
867 my_ncol =
SIZE(vec_b, 2)
868 IF (
PRESENT(ncol)) my_ncol = ncol
882 IF (my_ncol /= 1)
THEN
883 CALL dgemm(
'N',
'N', &
884 SIZE(data_d, 1), my_ncol,
SIZE(data_d, 2), &
885 my_alpha, data_d(1, 1),
SIZE(data_d, 1), &
886 vec_b(coloff, 1),
SIZE(vec_b, 1), &
887 1.0_dp, vec_c(rowoff, 1),
SIZE(vec_c, 1))
889 CALL dgemv(
'N',
SIZE(data_d, 1),
SIZE(data_d, 2), &
890 my_alpha, data_d(1, 1),
SIZE(data_d, 1), &
891 vec_b(coloff, 1), 1, &
892 1.0_dp, vec_c(rowoff, 1), 1)
905 IF (my_ncol /= 1)
THEN
906 CALL dgemm(
'T',
'N', &
907 SIZE(data_d, 2), my_ncol,
SIZE(data_d, 1), &
908 my_alpha2, data_d(1, 1),
SIZE(data_d, 1), &
909 vec_b(rowoff, 1),
SIZE(vec_b, 1), &
910 1.0_dp, vec_c(coloff, 1),
SIZE(vec_c, 1))
912 CALL dgemv(
'T',
SIZE(data_d, 1),
SIZE(data_d, 2), &
913 my_alpha2, data_d(1, 1),
SIZE(data_d, 1), &
914 vec_b(rowoff, 1), 1, &
915 1.0_dp, vec_c(coloff, 1), 1)
922 CALL timestop(timing_handle)
943 INTEGER,
INTENT(IN) :: ncol
944 REAL(
dp),
INTENT(IN),
OPTIONAL :: alpha, beta
946 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_dbcsr_sm_fm_multiply'
948 INTEGER :: a_ncol, a_nrow, b_ncol, b_nrow, c_ncol, &
949 c_nrow, k_in, k_out, timing_handle, &
951 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_blk_size_right_in, &
952 col_blk_size_right_out, col_dist, &
953 row_blk_size, row_dist
956 REAL(
dp) :: my_alpha, my_beta
958 CALL timeset(routinen, timing_handle)
962 IF (
PRESENT(alpha)) my_alpha = alpha
963 IF (
PRESENT(beta)) my_beta = beta
966 CALL cp_fm_get_info(fm_in, ncol_global=b_ncol, nrow_global=b_nrow)
967 CALL cp_fm_get_info(fm_out, ncol_global=c_ncol, nrow_global=c_nrow)
968 CALL dbcsr_get_info(matrix, nfullrows_total=a_nrow, nfullcols_total=a_ncol)
982 IF (ncol > 0 .AND. k_out > 0 .AND. k_in > 0)
THEN
983 CALL dbcsr_get_info(matrix, row_blk_size=row_blk_size, col_blk_size=col_blk_size, distribution=dist)
986 CALL dbcsr_create(in,
"D", dist_right_in, dbcsr_type_no_symmetry, &
987 col_blk_size, col_blk_size_right_in)
992 row_dist=row_dist, col_dist=col_dist)
993 ALLOCATE (col_blk_size_right_out(
SIZE(col_blk_size_right_in)))
994 col_blk_size_right_out = col_blk_size_right_in
995 CALL match_col_sizes(col_blk_size_right_out, col_blk_size_right_in, k_out)
1002 CALL dbcsr_create(out,
"D", product_dist, dbcsr_type_no_symmetry, &
1003 row_blk_size, col_blk_size_right_out)
1006 IF (ncol /= k_out .OR. my_beta /= 0.0_dp)
THEN
1010 CALL timeset(routinen//
'_core', timing_handle_mult)
1011 CALL dbcsr_multiply(
"N",
"N", my_alpha, matrix, in, my_beta, out, &
1013 CALL timestop(timing_handle_mult)
1019 DEALLOCATE (col_blk_size_right_in, col_blk_size_right_out)
1025 CALL timestop(timing_handle)
1035 SUBROUTINE match_col_sizes(sizes1, sizes2, full_num)
1036 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: sizes1
1037 INTEGER,
DIMENSION(:),
INTENT(IN) :: sizes2
1038 INTEGER,
INTENT(IN) :: full_num
1040 INTEGER :: left, n1, n2, p, rm, used
1045 cpabort(
"distributions must be equal!")
1047 sizes1(1:n1) = sizes2(1:n1)
1048 used = sum(sizes1(1:n1))
1052 IF (used < full_num)
THEN
1053 sizes1(n1) = sizes1(n1) + full_num - used
1055 left = used - full_num
1057 DO WHILE (left > 0 .AND. p > 0)
1058 rm = min(left, sizes1(p))
1059 sizes1(p) = sizes1(p) - rm
1064 END SUBROUTINE match_col_sizes
1085 TYPE(
dbcsr_type),
INTENT(INOUT) :: sparse_matrix
1087 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_g
1088 INTEGER,
INTENT(IN) :: ncol
1089 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: alpha
1090 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
1091 INTEGER,
INTENT(IN),
OPTIONAL :: symmetry_mode
1093 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_dbcsr_plus_fm_fm_t'
1095 INTEGER :: k, my_symmetry_mode, nao, npcols, &
1097 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size_left, col_dist_left, &
1098 row_blk_size, row_dist
1099 LOGICAL :: check_product, my_keep_sparsity
1100 REAL(kind=
dp) :: my_alpha, norm
1104 TYPE(
dbcsr_type) :: mat_g, mat_v, sparse_matrix2, &
1107 check_product = .false.
1109 CALL timeset(routinen, timing_handle)
1111 my_keep_sparsity = .true.
1112 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
1114 my_symmetry_mode = 0
1115 IF (
PRESENT(symmetry_mode)) my_symmetry_mode = symmetry_mode
1117 NULLIFY (col_dist_left)
1121 cpabort(
"sparse_matrix must pre-exist")
1129 CALL create_bl_distribution(col_dist_left, col_blk_size_left, k, npcols)
1131 row_dist=row_dist, col_dist=col_dist_left)
1132 DEALLOCATE (col_dist_left)
1134 CALL dbcsr_create(mat_v,
"DBCSR matrix_v", dist_left, dbcsr_type_no_symmetry, &
1135 row_blk_size, col_blk_size_left)
1140 IF (
PRESENT(matrix_g))
THEN
1141 CALL dbcsr_create(mat_g,
"DBCSR matrix_g", dist_left, dbcsr_type_no_symmetry, &
1142 row_blk_size, col_blk_size_left)
1146 DEALLOCATE (col_blk_size_left)
1150 IF (check_product)
THEN
1152 CALL cp_fm_struct_create(fm_struct_tmp, context=matrix_v%matrix_struct%context, nrow_global=nao, &
1153 ncol_global=nao, para_env=matrix_v%matrix_struct%para_env)
1154 CALL cp_fm_create(fm_matrix, fm_struct_tmp, name=
"fm matrix")
1157 CALL dbcsr_copy(sparse_matrix3, sparse_matrix)
1161 IF (
PRESENT(alpha)) my_alpha = alpha
1162 IF (
PRESENT(matrix_g))
THEN
1163 IF (my_symmetry_mode == 1)
THEN
1166 1.0_dp, sparse_matrix, &
1167 retain_sparsity=my_keep_sparsity, &
1170 1.0_dp, sparse_matrix, &
1171 retain_sparsity=my_keep_sparsity, &
1173 ELSE IF (my_symmetry_mode == -1)
THEN
1176 1.0_dp, sparse_matrix, &
1177 retain_sparsity=my_keep_sparsity, &
1180 1.0_dp, sparse_matrix, &
1181 retain_sparsity=my_keep_sparsity, &
1186 1.0_dp, sparse_matrix, &
1187 retain_sparsity=my_keep_sparsity, &
1192 1.0_dp, sparse_matrix, &
1193 retain_sparsity=my_keep_sparsity, &
1197 IF (check_product)
THEN
1198 IF (
PRESENT(matrix_g))
THEN
1199 IF (my_symmetry_mode == 1)
THEN
1200 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_v, matrix_g, &
1202 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_g, matrix_v, &
1204 ELSE IF (my_symmetry_mode == -1)
THEN
1205 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, 0.5_dp*my_alpha, matrix_v, matrix_g, &
1207 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, -0.5_dp*my_alpha, matrix_g, matrix_v, &
1210 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, my_alpha, matrix_v, matrix_g, &
1214 CALL cp_fm_gemm(
"N",
"T", nao, nao, ncol, my_alpha, matrix_v, matrix_v, &
1218 CALL dbcsr_copy(sparse_matrix2, sparse_matrix)
1219 CALL dbcsr_scale(sparse_matrix2, alpha_scalar=0.0_dp)
1220 CALL copy_fm_to_dbcsr(fm_matrix, sparse_matrix2, keep_sparsity=my_keep_sparsity)
1221 CALL dbcsr_add(sparse_matrix2, sparse_matrix, alpha_scalar=1.0_dp, &
1222 beta_scalar=-1.0_dp)
1224 WRITE (*, *)
'nao=', nao,
' k=', k,
' ncol=', ncol,
' my_alpha=', my_alpha
1225 WRITE (*, *)
'PRESENT (matrix_g)',
PRESENT(matrix_g)
1227 WRITE (*, *)
'norm(sm+alpha*v*g^t - fm+alpha*v*g^t)/n=', norm/real(nao,
dp)
1235 CALL timestop(timing_handle)
1255 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size_right_in, row_blk_size
1263 CALL dbcsr_create(matrix,
"D", dist_right_in, dbcsr_type_no_symmetry, &
1264 row_blk_size, col_blk_size_right_in)
1267 DEALLOCATE (col_blk_size_right_in)
1284 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix, template
1285 INTEGER,
INTENT(IN) :: m, n
1286 CHARACTER,
INTENT(IN),
OPTIONAL :: sym
1289 INTEGER :: npcols, nprows
1290 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_dist, row_blk_size, &
1294 CALL dbcsr_get_info(template, matrix_type=mysym, distribution=tmpl_dist)
1296 IF (
PRESENT(sym)) mysym = sym
1298 NULLIFY (row_dist, col_dist)
1299 NULLIFY (row_blk_size, col_blk_size)
1303 CALL create_bl_distribution(row_dist, row_blk_size, m, nprows)
1304 CALL create_bl_distribution(col_dist, col_blk_size, n, npcols)
1306 row_dist=row_dist, col_dist=col_dist, &
1308 reuse_arrays=.true.)
1310 CALL dbcsr_create(matrix,
"m_n_template", dist_m_n, mysym, &
1311 row_blk_size, col_blk_size, reuse_arrays=.true.)
1327 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix, template
1329 CHARACTER,
OPTIONAL :: sym
1333 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, col_dist, row_blk_size, &
1338 IF (
PRESENT(sym)) mysym = sym
1345 NULLIFY (col_dist, col_blk_size)
1346 CALL create_bl_distribution(col_dist, col_blk_size, n, npcols)
1348 row_dist=row_dist, col_dist=col_dist)
1351 CALL dbcsr_create(matrix,
"m_n_template", dist_m_n, mysym, row_blk_size, col_blk_size)
1353 DEALLOCATE (col_dist, col_blk_size)
1368 SUBROUTINE create_bl_distribution(block_distribution, &
1369 block_size, nelements, nbins)
1370 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: block_distribution, block_size
1371 INTEGER,
INTENT(IN) :: nelements, nbins
1373 CHARACTER(len=*),
PARAMETER :: routinen =
'create_bl_distribution', &
1374 routinep = modulen//
':'//routinen
1376 INTEGER :: bin, blk_layer, element_stack, els, &
1377 estimated_blocks, max_blocks_per_bin, &
1378 nblks, nblocks, stat
1379 INTEGER,
DIMENSION(:),
POINTER :: blk_dist, blk_sizes
1383 NULLIFY (block_distribution)
1384 NULLIFY (block_size)
1386 IF (nelements > 0)
THEN
1389 max_blocks_per_bin = ceiling(real(nblocks, kind=
dp)/real(nbins, kind=
dp))
1392 WRITE (*,
'(1X,A,1X,A,I7,A,I7,A)') routinep,
"For", nelements, &
1393 " elements and", nbins,
" bins"
1394 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1396 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1398 WRITE (*,
'(1X,A,1X,A,I7,A)') routinep,
"There are", &
1399 max_blocks_per_bin,
" max blocks/bin"
1402 estimated_blocks = max_blocks_per_bin*nbins
1403 ALLOCATE (blk_dist(estimated_blocks), stat=stat)
1407 ALLOCATE (blk_sizes(estimated_blocks), stat=stat)
1409 cpabort(
"blk_sizes")
1413 DO blk_layer = 1, max_blocks_per_bin
1414 DO bin = 0, nbins - 1
1417 element_stack = element_stack + els
1419 blk_dist(nblks) = bin
1420 blk_sizes(nblks) = els
1421 IF (debug_mod)
WRITE (*,
'(1X,A,I5,A,I5,A,I5)') routinep//
" Assigning", &
1422 els,
" elements as block", nblks,
" to bin", bin
1427 IF (nblks == estimated_blocks)
THEN
1428 block_distribution => blk_dist
1429 block_size => blk_sizes
1431 ALLOCATE (block_distribution(nblks), stat=stat)
1435 block_distribution(:) = blk_dist(1:nblks)
1436 DEALLOCATE (blk_dist)
1437 ALLOCATE (block_size(nblks), stat=stat)
1439 cpabort(
"blk_sizes")
1441 block_size(:) = blk_sizes(1:nblks)
1442 DEALLOCATE (blk_sizes)
1445 ALLOCATE (block_distribution(0), stat=stat)
1449 ALLOCATE (block_size(0), stat=stat)
1451 cpabort(
"blk_sizes")
14541579
FORMAT(i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5, 1x, i5)
1456 WRITE (*,
'(1X,A,A)') routinep//
" Distribution"
1457 WRITE (*, 1579) block_distribution(:)
1458 WRITE (*,
'(1X,A,A)') routinep//
" Sizes"
1459 WRITE (*, 1579) block_size(:)
1461 END SUBROUTINE create_bl_distribution
1475 right_col_blk_sizes)
1478 INTEGER,
INTENT(IN) :: ncolumns
1479 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: right_col_blk_sizes
1481 INTEGER :: multiplicity, ncols, nimages, npcols, &
1483 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: tmp_images
1484 INTEGER,
DIMENSION(:),
POINTER :: old_col_dist, right_col_dist, &
1489 col_dist=old_col_dist, &
1494 CALL create_bl_distribution(right_col_dist, right_col_blk_sizes, ncolumns, npcols)
1496 ALLOCATE (right_row_dist(ncols), tmp_images(ncols))
1497 nimages =
lcm(nprows, npcols)/nprows
1498 multiplicity = nprows/
gcd(nprows, npcols)
1499 CALL rebin_distribution(right_row_dist, tmp_images, old_col_dist, nprows, multiplicity, nimages)
1502 template=dist_left, &
1503 row_dist=right_row_dist, &
1504 col_dist=right_col_dist, &
1507 reuse_arrays=.true.)
1508 DEALLOCATE (tmp_images)
1544 SUBROUTINE rebin_distribution(new_bins, images, source_bins, &
1545 nbins, multiplicity, nimages)
1546 INTEGER,
DIMENSION(:),
INTENT(OUT) :: new_bins, images
1547 INTEGER,
DIMENSION(:),
INTENT(IN) :: source_bins
1548 INTEGER,
INTENT(IN) :: nbins, multiplicity, nimages
1550 INTEGER :: bin, i, old_nbins, virtual_bin
1551 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: bin_multiplier
1555 IF (mod(nbins*nimages, multiplicity) /= 0)
THEN
1556 cpwarn(
"mulitplicity is not divisor of new process grid coordinate")
1558 old_nbins = (nbins*nimages)/multiplicity
1559 ALLOCATE (bin_multiplier(0:old_nbins - 1))
1560 bin_multiplier(:) = 0
1561 DO i = 1,
SIZE(new_bins)
1562 IF (i <=
SIZE(source_bins))
THEN
1563 bin = source_bins(i)
1566 bin = mod(i, old_nbins)
1568 virtual_bin = bin*multiplicity + bin_multiplier(bin)
1569 new_bins(i) = virtual_bin/nimages
1570 images(i) = 1 + mod(virtual_bin, nimages)
1571 bin_multiplier(bin) = bin_multiplier(bin) + 1
1572 IF (bin_multiplier(bin) >= multiplicity)
THEN
1573 bin_multiplier(bin) = 0
1576 END SUBROUTINE rebin_distribution
1593 SUBROUTINE dbcsr_create_dist_block_cyclic(dist, nrows, ncolumns, &
1594 nrow_block, ncol_block, group_handle, pgrid, row_blk_sizes, col_blk_sizes)
1596 INTEGER,
INTENT(IN) :: nrows, ncolumns, nrow_block, ncol_block, &
1598 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
1599 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: row_blk_sizes, col_blk_sizes
1601 CHARACTER(len=*),
PARAMETER :: routinen =
'dbcsr_create_dist_block_cyclic'
1603 INTEGER :: nblkcols, nblkrows, npcols, nprows, &
1605 INTEGER,
DIMENSION(:),
POINTER :: cd_data, rd_data
1608 IF (nrow_block == 0)
THEN
1612 nblkrows = nrows/nrow_block
1613 sz = mod(nrows, nrow_block)
1615 IF (sz > 0) nblkrows = nblkrows + 1
1616 ALLOCATE (row_blk_sizes(nblkrows), rd_data(nblkrows))
1617 row_blk_sizes = nrow_block
1618 IF (sz /= 0) row_blk_sizes(nblkrows) = sz
1621 IF (ncol_block == 0)
THEN
1625 nblkcols = ncolumns/ncol_block
1626 sz = mod(ncolumns, ncol_block)
1628 IF (sz > 0) nblkcols = nblkcols + 1
1629 ALLOCATE (col_blk_sizes(nblkcols), cd_data(nblkcols))
1630 col_blk_sizes = ncol_block
1631 IF (sz /= 0) col_blk_sizes(nblkcols) = sz
1634 WRITE (*, *) routinen//
" nrows,nrow_block,nblkrows=", &
1635 nrows, nrow_block, nblkrows
1636 WRITE (*, *) routinen//
" ncols,ncol_block,nblkcols=", &
1637 ncolumns, ncol_block, nblkcols
1640 nprows =
SIZE(pgrid, 1)
1641 DO pdim = 0, min(nprows - 1, nblkrows - 1)
1642 rd_data(1 + pdim:nblkrows:nprows) = pdim
1645 npcols =
SIZE(pgrid, 2)
1646 DO pdim = 0, min(npcols - 1, nblkcols - 1)
1647 cd_data(1 + pdim:nblkcols:npcols) = pdim
1651 WRITE (*, *) routinen//
" row_dist", &
1653 WRITE (*, *) routinen//
" col_dist", &
1658 group=group_handle, pgrid=pgrid, &
1661 reuse_arrays=.true.)
1663 END SUBROUTINE dbcsr_create_dist_block_cyclic
1672 SUBROUTINE allocate_dbcsr_matrix_set_1d(matrix_set, nmatrix)
1673 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_set
1674 INTEGER,
INTENT(IN) :: nmatrix
1679 ALLOCATE (matrix_set(nmatrix))
1680 DO imatrix = 1, nmatrix
1681 NULLIFY (matrix_set(imatrix)%matrix)
1683 END SUBROUTINE allocate_dbcsr_matrix_set_1d
1693 SUBROUTINE allocate_dbcsr_matrix_set_2d(matrix_set, nmatrix, mmatrix)
1694 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_set
1695 INTEGER,
INTENT(IN) :: nmatrix, mmatrix
1697 INTEGER :: imatrix, jmatrix
1700 ALLOCATE (matrix_set(nmatrix, mmatrix))
1701 DO jmatrix = 1, mmatrix
1702 DO imatrix = 1, nmatrix
1703 NULLIFY (matrix_set(imatrix, jmatrix)%matrix)
1706 END SUBROUTINE allocate_dbcsr_matrix_set_2d
1717 SUBROUTINE allocate_dbcsr_matrix_set_3d(matrix_set, nmatrix, mmatrix, pmatrix)
1718 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :),
POINTER :: matrix_set
1719 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix
1721 INTEGER :: imatrix, jmatrix, kmatrix
1724 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix))
1725 DO kmatrix = 1, pmatrix
1726 DO jmatrix = 1, mmatrix
1727 DO imatrix = 1, nmatrix
1728 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix)%matrix)
1732 END SUBROUTINE allocate_dbcsr_matrix_set_3d
1744 SUBROUTINE allocate_dbcsr_matrix_set_4d(matrix_set, nmatrix, mmatrix, pmatrix, qmatrix)
1745 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :, :),
POINTER :: matrix_set
1746 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix, qmatrix
1748 INTEGER :: imatrix, jmatrix, kmatrix, lmatrix
1751 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix, qmatrix))
1752 DO lmatrix = 1, qmatrix
1753 DO kmatrix = 1, pmatrix
1754 DO jmatrix = 1, mmatrix
1755 DO imatrix = 1, nmatrix
1756 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix, lmatrix)%matrix)
1761 END SUBROUTINE allocate_dbcsr_matrix_set_4d
1774 SUBROUTINE allocate_dbcsr_matrix_set_5d(matrix_set, nmatrix, mmatrix, pmatrix, qmatrix, smatrix)
1776 POINTER :: matrix_set
1777 INTEGER,
INTENT(IN) :: nmatrix, mmatrix, pmatrix, qmatrix, &
1780 INTEGER :: hmatrix, imatrix, jmatrix, kmatrix, &
1784 ALLOCATE (matrix_set(nmatrix, mmatrix, pmatrix, qmatrix, smatrix))
1785 DO hmatrix = 1, smatrix
1786 DO lmatrix = 1, qmatrix
1787 DO kmatrix = 1, pmatrix
1788 DO jmatrix = 1, mmatrix
1789 DO imatrix = 1, nmatrix
1790 NULLIFY (matrix_set(imatrix, jmatrix, kmatrix, lmatrix, hmatrix)%matrix)
1796 END SUBROUTINE allocate_dbcsr_matrix_set_5d
1804 SUBROUTINE deallocate_dbcsr_matrix_set_1d(matrix_set)
1806 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_set
1810 IF (
ASSOCIATED(matrix_set))
THEN
1811 DO imatrix = lbound(matrix_set, 1), ubound(matrix_set, 1)
1814 DEALLOCATE (matrix_set)
1817 END SUBROUTINE deallocate_dbcsr_matrix_set_1d
1825 SUBROUTINE deallocate_dbcsr_matrix_set_2d(matrix_set)
1827 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_set
1829 INTEGER :: imatrix, jmatrix
1831 IF (
ASSOCIATED(matrix_set))
THEN
1832 DO jmatrix = lbound(matrix_set, 2), ubound(matrix_set, 2)
1833 DO imatrix = lbound(matrix_set, 1), ubound(matrix_set, 1)
1837 DEALLOCATE (matrix_set)
1839 END SUBROUTINE deallocate_dbcsr_matrix_set_2d
1847 SUBROUTINE deallocate_dbcsr_matrix_set_3d(matrix_set)
1849 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :),
POINTER :: matrix_set
1851 INTEGER :: imatrix, jmatrix, kmatrix
1853 IF (
ASSOCIATED(matrix_set))
THEN
1854 DO kmatrix = lbound(matrix_set, 3), ubound(matrix_set, 3)
1855 DO jmatrix = lbound(matrix_set, 2), ubound(matrix_set, 2)
1856 DO imatrix = lbound(matrix_set, 1), ubound(matrix_set, 1)
1861 DEALLOCATE (matrix_set)
1863 END SUBROUTINE deallocate_dbcsr_matrix_set_3d
1871 SUBROUTINE deallocate_dbcsr_matrix_set_4d(matrix_set)
1873 TYPE(
dbcsr_p_type),
DIMENSION(:, :, :, :),
POINTER :: matrix_set
1875 INTEGER :: imatrix, jmatrix, kmatrix, lmatrix
1877 IF (
ASSOCIATED(matrix_set))
THEN
1878 DO lmatrix = lbound(matrix_set, 4), ubound(matrix_set, 4)
1879 DO kmatrix = lbound(matrix_set, 3), ubound(matrix_set, 3)
1880 DO jmatrix = lbound(matrix_set, 2), ubound(matrix_set, 2)
1881 DO imatrix = lbound(matrix_set, 1), ubound(matrix_set, 1)
1887 DEALLOCATE (matrix_set)
1889 END SUBROUTINE deallocate_dbcsr_matrix_set_4d
1897 SUBROUTINE deallocate_dbcsr_matrix_set_5d(matrix_set)
1900 POINTER :: matrix_set
1902 INTEGER :: hmatrix, imatrix, jmatrix, kmatrix, &
1905 IF (
ASSOCIATED(matrix_set))
THEN
1906 DO hmatrix = lbound(matrix_set, 5), ubound(matrix_set, 5)
1907 DO lmatrix = lbound(matrix_set, 4), ubound(matrix_set, 4)
1908 DO kmatrix = lbound(matrix_set, 3), ubound(matrix_set, 3)
1909 DO jmatrix = lbound(matrix_set, 2), ubound(matrix_set, 2)
1910 DO imatrix = lbound(matrix_set, 1), ubound(matrix_set, 1)
1917 DEALLOCATE (matrix_set)
1919 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 copy_dbcsr_to_fm(matrix, fm, plan, check_plan)
Copy a DBCSR matrix to a BLACS matrix.
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_sum_many(matrix_c, matrix_a, alpha)
Sum local, nonsymmetric matrices in history order, using bounded per-worker storage....
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_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 copy_local_to_dbcsr(matrix, dense)
Store a single-rank, nonsymmetric matrix without redistribution.
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.
subroutine, public copy_dbcsr_to_local(matrix, dense)
Load a single-rank, nonsymmetric matrix without redistribution.
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 int_8
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