9 USE iso_c_binding,
ONLY: c_associated, c_bool, c_char, c_double, c_f_pointer, c_funloc, c_funptr, &
10 c_int, c_int64_t, c_null_char, c_null_ptr, c_ptr
19#define DBM_VALIDATE_NBLOCKS_MATCH .TRUE.
20#define DBM_VALIDATE_THRESHOLD 5e-10_dp
22#if defined(DBM_VALIDATE_AGAINST_DBCSR)
23 USE dbcsr_block_access,
ONLY: dbcsr_get_block_p, &
26 USE dbcsr_dist_methods,
ONLY: dbcsr_distribution_col_dist, &
27 dbcsr_distribution_hold, &
28 dbcsr_distribution_new, &
29 dbcsr_distribution_release, &
30 dbcsr_distribution_row_dist
31 USE dbcsr_dist_operations,
ONLY: dbcsr_get_stored_coordinates
32 USE dbcsr_dist_util,
ONLY: dbcsr_checksum
33 USE dbcsr_iterator_operations,
ONLY: dbcsr_iterator_blocks_left, &
34 dbcsr_iterator_next_block, &
35 dbcsr_iterator_start, &
37 USE dbcsr_methods,
ONLY: dbcsr_col_block_sizes, &
38 dbcsr_get_num_blocks, &
43 USE dbcsr_mp_methods,
ONLY: dbcsr_mp_new
44 USE dbcsr_multiply_api,
ONLY: dbcsr_multiply
45 USE dbcsr_operations,
ONLY: dbcsr_add, &
53 USE dbcsr_transformations,
ONLY: dbcsr_redistribute
54 USE dbcsr_types,
ONLY: dbcsr_distribution_obj, &
60 dbcsr_type_no_symmetry, &
62 USE dbcsr_work_operations,
ONLY: dbcsr_create, &
64 USE dbcsr_data_methods,
ONLY: dbcsr_scalar
67#include "../base/base_uses.f90"
73 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dbm_api'
123 TYPE(C_PTR) :: c_ptr = c_null_ptr
124#if defined(DBM_VALIDATE_AGAINST_DBCSR)
125 TYPE(dbcsr_distribution_obj) :: dbcsr
131 TYPE(C_PTR) :: c_ptr = c_null_ptr
132#if defined(DBM_VALIDATE_AGAINST_DBCSR)
133 TYPE(dbcsr_type) :: dbcsr
139 TYPE(C_PTR) :: c_ptr = c_null_ptr
144#if defined(DBM_VALIDATE_AGAINST_DBCSR)
151 TYPE(dbm_type),
INTENT(IN) :: matrix
153 INTEGER :: col, col_size, col_size_dbcsr, i, j, &
154 num_blocks, num_blocks_dbcsr, &
155 num_blocks_diff, row, row_size, &
157 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: local_cols, local_rows
158 LOGICAL :: transposed
159 REAL(dp) :: norm2, rel_diff
160 REAL(dp),
DIMENSION(:, :),
POINTER :: block, block_dbcsr
161 TYPE(C_PTR) :: block_c
162 TYPE(dbcsr_iterator) :: iter
164 SUBROUTINE dbm_get_block_p_c(matrix, row, col, block, row_size, col_size) &
165 BIND(C, name="dbm_get_block_p")
166 IMPORT :: c_ptr, c_int
167 TYPE(C_PTR),
VALUE :: matrix
168 INTEGER(kind=C_INT),
VALUE :: row
169 INTEGER(kind=C_INT),
VALUE :: col
171 INTEGER(kind=C_INT) :: row_size
172 INTEGER(kind=C_INT) :: col_size
173 END SUBROUTINE dbm_get_block_p_c
180 num_blocks_dbcsr = dbcsr_get_num_blocks(matrix%dbcsr)
182 num_blocks_diff = abs(num_blocks - num_blocks_dbcsr)
183 IF (num_blocks_diff /= 0)
THEN
184 WRITE (*, *)
"num_blocks mismatch dbcsr:", num_blocks_dbcsr,
"new:", num_blocks
185 IF (dbm_validate_nblocks_match) &
186 cpabort(
"num_blocks mismatch")
189 IF (dbm_validate_nblocks_match)
THEN
190 cpassert(
dbm_get_nze(matrix) == dbcsr_get_nze(matrix%dbcsr))
195 CALL dbcsr_iterator_start(iter, matrix%dbcsr)
196 DO WHILE (dbcsr_iterator_blocks_left(iter))
197 CALL dbcsr_iterator_next_block(iter, row=row, column=col, block=block_dbcsr, &
198 transposed=transposed, &
199 row_size=row_size_dbcsr, col_size=col_size_dbcsr)
200 cpassert(.NOT. transposed)
201 CALL dbm_get_block_p_c(matrix=matrix%c_ptr, row=row - 1, col=col - 1, &
202 block=block_c, row_size=row_size, col_size=col_size)
204 cpassert(row_size == row_size_dbcsr .AND. col_size == col_size_dbcsr)
205 IF (
SIZE(block_dbcsr) == 0)
THEN
208 IF (.NOT. c_associated(block_c))
THEN
209 cpassert(maxval(abs(block_dbcsr)) < dbm_validate_threshold)
213 CALL c_f_pointer(block_c, block, shape=(/row_size, col_size/))
216 rel_diff = abs(block(i, j) - block_dbcsr(i, j))/max(1.0_dp, abs(block_dbcsr(i, j)))
217 IF (rel_diff > dbm_validate_threshold)
THEN
218 WRITE (*, *)
"row:", row,
"col:", col,
"i:", i,
"j:", j,
"rel_diff:", rel_diff
219 WRITE (*, *)
"values dbcsr:", block_dbcsr(i, j),
"new:", block(i, j)
220 cpabort(
"block value mismatch")
224 norm2 = norm2 + sum(block**2)
225 block_dbcsr(:, :) = block(:, :)
227 CALL dbcsr_iterator_stop(iter)
250 TYPE(
dbm_type),
INTENT(IN) :: matrix
264 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
265 CHARACTER(len=*),
INTENT(IN) :: name
266 TYPE(
dbm_type),
INTENT(IN) :: template
268 INTEGER,
CONTIGUOUS,
DIMENSION(:),
POINTER :: col_block_sizes, row_block_sizes
277 row_block_sizes=row_block_sizes, &
278 col_block_sizes=col_block_sizes)
291 SUBROUTINE dbm_create(matrix, name, dist, row_block_sizes, col_block_sizes)
292 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
293 CHARACTER(len=*),
INTENT(IN) :: name
295 INTEGER,
CONTIGUOUS,
DIMENSION(:),
INTENT(IN), &
296 POINTER :: row_block_sizes, col_block_sizes
299 SUBROUTINE dbm_create_c(matrix, dist, name, nrows, ncols, row_sizes, col_sizes) &
300 BIND(C, name="dbm_create")
301 IMPORT :: c_ptr, c_char, c_int
302 TYPE(c_ptr) :: matrix
303 TYPE(c_ptr),
VALUE :: dist
304 CHARACTER(kind=C_CHAR),
DIMENSION(*) :: name
305 INTEGER(kind=C_INT),
VALUE :: nrows
306 INTEGER(kind=C_INT),
VALUE :: ncols
307 INTEGER(kind=C_INT),
DIMENSION(*) :: row_sizes
308 INTEGER(kind=C_INT),
DIMENSION(*) :: col_sizes
309 END SUBROUTINE dbm_create_c
312 cpassert(.NOT. c_associated(matrix%c_ptr))
313 CALL dbm_create_c(matrix=matrix%c_ptr, &
315 name=trim(name)//c_null_char, &
316 nrows=
SIZE(row_block_sizes), &
317 ncols=
SIZE(col_block_sizes), &
318 row_sizes=row_block_sizes, &
319 col_sizes=col_block_sizes)
320 cpassert(c_associated(matrix%c_ptr))
322#if defined(DBM_VALIDATE_AGAINST_DBCSR)
323 CALL dbcsr_create(matrix%dbcsr, name=name, dist=dist%dbcsr, &
324 matrix_type=dbcsr_type_no_symmetry, &
325 row_blk_size=row_block_sizes, col_blk_size=col_block_sizes, &
326 data_type=dbcsr_type_real_8)
338 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
342#if defined(DBM_VALIDATE_AGAINST_DBCSR)
343 CALL dbcsr_finalize(matrix%dbcsr)
353 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
356 SUBROUTINE dbm_release_c(matrix) &
357 BIND(C, name="dbm_release")
359 TYPE(c_ptr),
VALUE :: matrix
360 END SUBROUTINE dbm_release_c
363 CALL dbm_release_c(matrix=matrix%c_ptr)
364 matrix%c_ptr = c_null_ptr
366#if defined(DBM_VALIDATE_AGAINST_DBCSR)
367 CALL dbcsr_release(matrix%dbcsr)
379 TYPE(
dbm_type),
INTENT(INOUT) :: matrix_a
380 TYPE(
dbm_type),
INTENT(IN) :: matrix_b
382 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbm_copy'
386 SUBROUTINE dbm_copy_c(matrix_a, matrix_b) &
387 BIND(C, name="dbm_copy")
389 TYPE(c_ptr),
VALUE :: matrix_a
390 TYPE(c_ptr),
VALUE :: matrix_b
391 END SUBROUTINE dbm_copy_c
394 CALL timeset(routinen, handle)
395 CALL dbm_copy_c(matrix_a=matrix_a%c_ptr, matrix_b=matrix_b%c_ptr)
397#if defined(DBM_VALIDATE_AGAINST_DBCSR)
398 CALL dbcsr_copy(matrix_a%dbcsr, matrix_b%dbcsr)
401 CALL timestop(handle)
411 TYPE(
dbm_type),
INTENT(IN) :: matrix
412 TYPE(
dbm_type),
INTENT(INOUT) :: redist
414 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbm_redistribute'
418 SUBROUTINE dbm_redistribute_c(matrix, redist) &
419 BIND(C, name="dbm_redistribute")
421 TYPE(c_ptr),
VALUE :: matrix
422 TYPE(c_ptr),
VALUE :: redist
423 END SUBROUTINE dbm_redistribute_c
426 CALL timeset(routinen, handle)
427 CALL dbm_redistribute_c(matrix=matrix%c_ptr, redist=redist%c_ptr)
429#if defined(DBM_VALIDATE_AGAINST_DBCSR)
430 CALL dbcsr_redistribute(matrix%dbcsr, redist%dbcsr)
433 CALL timestop(handle)
448 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
449 INTEGER,
INTENT(IN) :: row, col
450 REAL(
dp),
DIMENSION(:, :),
INTENT(OUT),
POINTER :: block
451 INTEGER,
INTENT(OUT),
OPTIONAL :: row_size, col_size
453 INTEGER :: my_col_size, my_row_size
454 TYPE(c_ptr) :: block_c
456 SUBROUTINE dbm_get_block_p_c(matrix, row, col, block, row_size, col_size) &
457 BIND(C, name="dbm_get_block_p")
458 IMPORT :: c_ptr, c_int
459 TYPE(c_ptr),
VALUE :: matrix
460 INTEGER(kind=C_INT),
VALUE :: row
461 INTEGER(kind=C_INT),
VALUE :: col
463 INTEGER(kind=C_INT) :: row_size
464 INTEGER(kind=C_INT) :: col_size
465 END SUBROUTINE dbm_get_block_p_c
468 CALL dbm_get_block_p_c(matrix=matrix%c_ptr, row=row - 1, col=col - 1, &
469 block=block_c, row_size=my_row_size, col_size=my_col_size)
470 IF (c_associated(block_c))
THEN
471 CALL c_f_pointer(block_c, block, shape=(/my_row_size, my_col_size/))
475 IF (
PRESENT(row_size)) row_size = my_row_size
476 IF (
PRESENT(col_size)) col_size = my_col_size
490 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
491 INTEGER,
INTENT(IN) :: row, col
492 REAL(
dp),
CONTIGUOUS,
DIMENSION(:, :),
INTENT(IN) :: block
493 LOGICAL,
INTENT(IN),
OPTIONAL :: summation
495 LOGICAL :: my_summation
497 SUBROUTINE dbm_put_block_c(matrix, row, col, summation, block) &
498 BIND(C, name="dbm_put_block")
499 IMPORT :: c_ptr, c_int, c_bool, c_double
500 TYPE(c_ptr),
VALUE :: matrix
501 INTEGER(kind=C_INT),
VALUE :: row
502 INTEGER(kind=C_INT),
VALUE :: col
503 LOGICAL(kind=C_BOOL),
VALUE :: summation
504 REAL(kind=c_double),
DIMENSION(*) :: block
505 END SUBROUTINE dbm_put_block_c
508 my_summation = .false.
509 IF (
PRESENT(summation)) my_summation = summation
511 CALL dbm_put_block_c(matrix=matrix%c_ptr, &
512 row=row - 1, col=col - 1, &
513 summation=
LOGICAL(my_summation, C_BOOL), &
516#if defined(DBM_VALIDATE_AGAINST_DBCSR)
517 CALL dbcsr_put_block(matrix%dbcsr, row, col, block, summation=summation)
528 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
531 SUBROUTINE dbm_clear_c(matrix) &
532 BIND(C, name="dbm_clear")
534 TYPE(c_ptr),
VALUE :: matrix
535 END SUBROUTINE dbm_clear_c
538 CALL dbm_clear_c(matrix=matrix%c_ptr)
540#if defined(DBM_VALIDATE_AGAINST_DBCSR)
541 CALL dbcsr_clear(matrix%dbcsr)
554 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
555 REAL(
dp),
INTENT(IN) :: eps
557 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbm_filter'
561 SUBROUTINE dbm_filter_c(matrix, eps) &
562 BIND(C, name="dbm_filter")
563 IMPORT :: c_ptr, c_double
564 TYPE(c_ptr),
VALUE :: matrix
565 REAL(kind=c_double),
VALUE :: eps
566 END SUBROUTINE dbm_filter_c
569 CALL timeset(routinen, handle)
571 CALL dbm_filter_c(matrix=matrix%c_ptr, eps=eps)
573#if defined(DBM_VALIDATE_AGAINST_DBCSR)
574 CALL dbcsr_filter(matrix%dbcsr, eps)
577 CALL timestop(handle)
588 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
589 INTEGER,
DIMENSION(:),
INTENT(IN) :: rows, cols
591 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbm_reserve_blocks'
594 INTEGER(kind=C_INT),
DIMENSION(SIZE(rows)) :: cols_c, rows_c
596 SUBROUTINE dbm_reserve_blocks_c(matrix, nblocks, rows, cols) &
597 BIND(C, name="dbm_reserve_blocks")
598 IMPORT :: c_ptr, c_int
599 TYPE(c_ptr),
VALUE :: matrix
600 INTEGER(kind=C_INT),
VALUE :: nblocks
601 INTEGER(kind=C_INT),
DIMENSION(*) :: rows
602 INTEGER(kind=C_INT),
DIMENSION(*) :: cols
603 END SUBROUTINE dbm_reserve_blocks_c
606 CALL timeset(routinen, handle)
607 cpassert(
SIZE(rows) ==
SIZE(cols))
611 CALL dbm_reserve_blocks_c(matrix=matrix%c_ptr, &
612 nblocks=
SIZE(rows), &
616#if defined(DBM_VALIDATE_AGAINST_DBCSR)
617 CALL dbcsr_reserve_blocks(matrix%dbcsr, rows, cols)
620 CALL timestop(handle)
630 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
631 REAL(
dp),
INTENT(IN) :: alpha
633 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbm_scale'
637 SUBROUTINE dbm_scale_c(matrix, alpha) &
638 BIND(C, name="dbm_scale")
639 IMPORT :: c_ptr, c_double
640 TYPE(c_ptr),
VALUE :: matrix
641 REAL(kind=c_double),
VALUE :: alpha
642 END SUBROUTINE dbm_scale_c
645 CALL timeset(routinen, handle)
646 CALL dbm_scale_c(matrix=matrix%c_ptr, alpha=alpha)
648#if defined(DBM_VALIDATE_AGAINST_DBCSR)
649 CALL dbcsr_scale(matrix%dbcsr, alpha)
652 CALL timestop(handle)
661 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
663 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbm_zero'
667 SUBROUTINE dbm_zero_c(matrix) &
668 BIND(C, name="dbm_zero")
670 TYPE(c_ptr),
VALUE :: matrix
671 END SUBROUTINE dbm_zero_c
674 CALL timeset(routinen, handle)
675 CALL dbm_zero_c(matrix=matrix%c_ptr)
677#if defined(DBM_VALIDATE_AGAINST_DBCSR)
678 CALL dbcsr_zero(matrix%dbcsr)
681 CALL timestop(handle)
691 TYPE(
dbm_type),
INTENT(INOUT) :: matrix_a
692 TYPE(
dbm_type),
INTENT(IN) :: matrix_b
694 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbm_add'
698 SUBROUTINE dbm_add_c(matrix_a, matrix_b) &
699 BIND(C, name="dbm_add")
700 IMPORT :: c_ptr, c_double
701 TYPE(c_ptr),
VALUE :: matrix_a
702 TYPE(c_ptr),
VALUE :: matrix_b
703 END SUBROUTINE dbm_add_c
706 CALL timeset(routinen, handle)
709 CALL dbm_add_c(matrix_a=matrix_a%c_ptr, matrix_b=matrix_b%c_ptr)
711#if defined(DBM_VALIDATE_AGAINST_DBCSR)
712 CALL dbcsr_add(matrix_a%dbcsr, matrix_b%dbcsr)
715 CALL timestop(handle)
733 alpha, matrix_a, matrix_b, beta, matrix_c, &
734 retain_sparsity, filter_eps, flop)
735 LOGICAL,
INTENT(IN) :: transa, transb
736 REAL(kind=
dp),
INTENT(IN) :: alpha
737 TYPE(
dbm_type),
INTENT(IN) :: matrix_a, matrix_b
738 REAL(kind=
dp),
INTENT(IN) :: beta
739 TYPE(
dbm_type),
INTENT(INOUT) :: matrix_c
740 LOGICAL,
INTENT(IN),
OPTIONAL :: retain_sparsity
741 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: filter_eps
742 INTEGER(int_8),
INTENT(OUT),
OPTIONAL :: flop
744 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbm_multiply'
746 CHARACTER(LEN=1) :: transa_char, transb_char
748 INTEGER(int_8) :: flop_dbcsr, my_flop
749 LOGICAL :: my_retain_sparsity
750 REAL(kind=
dp) :: my_filter_eps
752 SUBROUTINE dbm_multiply_c(transa, transb, alpha, &
753 matrix_a, matrix_b, &
755 retain_sparsity, filter_eps, flop) &
756 BIND(C, name="dbm_multiply")
757 IMPORT :: c_ptr, c_double, c_bool, c_int64_t
758 LOGICAL(kind=C_BOOL),
VALUE :: transa
759 LOGICAL(kind=C_BOOL),
VALUE :: transb
760 REAL(kind=c_double),
VALUE :: alpha
761 TYPE(c_ptr),
VALUE :: matrix_a
762 TYPE(c_ptr),
VALUE :: matrix_b
763 REAL(kind=c_double),
VALUE :: beta
764 TYPE(c_ptr),
VALUE :: matrix_c
765 LOGICAL(kind=C_BOOL),
VALUE :: retain_sparsity
766 REAL(kind=c_double),
VALUE :: filter_eps
767 INTEGER(kind=C_INT64_T) :: flop
768 END SUBROUTINE dbm_multiply_c
771 CALL timeset(routinen, handle)
773 IF (
PRESENT(retain_sparsity))
THEN
774 my_retain_sparsity = retain_sparsity
776 my_retain_sparsity = .false.
779 IF (
PRESENT(filter_eps))
THEN
780 my_filter_eps = filter_eps
782 my_filter_eps = 0.0_dp
788 CALL dbm_multiply_c(transa=
LOGICAL(transa, C_BOOL), &
789 transb=logical(transb, c_bool), &
791 matrix_a=matrix_a%c_ptr, &
792 matrix_b=matrix_b%c_ptr, &
794 matrix_c=matrix_c%c_ptr, &
795 retain_sparsity=
LOGICAL(my_retain_sparsity, C_BOOL), &
796 filter_eps=my_filter_eps, &
799 IF (
PRESENT(flop))
THEN
803#if defined(DBM_VALIDATE_AGAINST_DBCSR)
805 transa_char = dbcsr_transpose
807 transa_char = dbcsr_no_transpose
810 transb_char = dbcsr_transpose
812 transb_char = dbcsr_no_transpose
814 CALL dbcsr_multiply(transa=transa_char, transb=transb_char, &
815 alpha=alpha, matrix_a=matrix_a%dbcsr, &
816 matrix_b=matrix_b%dbcsr, beta=beta, matrix_c=matrix_c%dbcsr, &
817 retain_sparsity=retain_sparsity, filter_eps=filter_eps, flop=flop_dbcsr)
818 cpassert(my_flop == flop_dbcsr)
822 mark_used(transa_char)
823 mark_used(transb_char)
824 mark_used(flop_dbcsr)
826 CALL timestop(handle)
837 TYPE(
dbm_type),
INTENT(IN) :: matrix
840 SUBROUTINE dbm_iterator_start_c(iterator, matrix) &
841 BIND(C, name="dbm_iterator_start")
843 TYPE(c_ptr) :: iterator
844 TYPE(c_ptr),
VALUE :: matrix
845 END SUBROUTINE dbm_iterator_start_c
848 cpassert(.NOT. c_associated(iterator%c_ptr))
849 CALL dbm_iterator_start_c(iterator=iterator%c_ptr, matrix=matrix%c_ptr)
850 cpassert(c_associated(iterator%c_ptr))
862 INTEGER :: num_blocks
865 FUNCTION dbm_iterator_num_blocks_c(iterator) &
866 BIND(C, name="dbm_iterator_num_blocks")
867 IMPORT :: c_ptr, c_int
868 TYPE(c_ptr),
VALUE :: iterator
869 INTEGER(kind=C_INT) :: dbm_iterator_num_blocks_c
870 END FUNCTION dbm_iterator_num_blocks_c
873 num_blocks = dbm_iterator_num_blocks_c(iterator%c_ptr)
884 LOGICAL :: blocks_left
887 FUNCTION dbm_iterator_blocks_left_c(iterator) &
888 BIND(C, name="dbm_iterator_blocks_left")
889 IMPORT :: c_ptr, c_bool
890 TYPE(c_ptr),
VALUE :: iterator
891 LOGICAL(C_BOOL) :: dbm_iterator_blocks_left_c
892 END FUNCTION dbm_iterator_blocks_left_c
895 blocks_left = dbm_iterator_blocks_left_c(iterator%c_ptr)
910 INTEGER,
INTENT(OUT) :: row, column
911 REAL(
dp),
DIMENSION(:, :),
INTENT(OUT),
OPTIONAL, &
913 INTEGER,
INTENT(OUT),
OPTIONAL :: row_size, col_size
915 INTEGER :: col0, my_col_size, my_row_size, row0
916 TYPE(c_ptr) :: block_c
918 SUBROUTINE dbm_iterator_next_block_c(iterator, row, col, block, row_size, col_size) &
919 BIND(C, name="dbm_iterator_next_block")
920 IMPORT :: c_ptr, c_int
921 TYPE(c_ptr),
VALUE :: iterator
922 INTEGER(kind=C_INT) :: row
923 INTEGER(kind=C_INT) :: col
925 INTEGER(kind=C_INT) :: row_size
926 INTEGER(kind=C_INT) :: col_size
927 END SUBROUTINE dbm_iterator_next_block_c
930 CALL dbm_iterator_next_block_c(iterator%c_ptr, row=row0, col=col0, block=block_c, &
931 row_size=my_row_size, col_size=my_col_size)
933 cpassert(c_associated(block_c))
934 IF (
PRESENT(block))
CALL c_f_pointer(block_c, block, shape=(/my_row_size, my_col_size/))
937 IF (
PRESENT(row_size)) row_size = my_row_size
938 IF (
PRESENT(col_size)) col_size = my_col_size
950 SUBROUTINE dbm_iterator_stop_c(iterator) &
951 BIND(C, name="dbm_iterator_stop")
953 TYPE(c_ptr),
VALUE :: iterator
954 END SUBROUTINE dbm_iterator_stop_c
957 CALL dbm_iterator_stop_c(iterator%c_ptr)
958 iterator%c_ptr = c_null_ptr
968 TYPE(
dbm_type),
INTENT(IN) :: matrix
972 FUNCTION dbm_checksum_c(matrix) &
973 BIND(C, name="dbm_checksum")
974 IMPORT :: c_ptr, c_double
975 TYPE(c_ptr),
VALUE :: matrix
976 REAL(c_double) :: dbm_checksum_c
977 END FUNCTION dbm_checksum_c
981 res = dbm_checksum_c(matrix%c_ptr)
983#if defined(DBM_VALIDATE_AGAINST_DBCSR)
984 cpassert(abs(res - dbcsr_checksum(matrix%dbcsr))/max(1.0_dp, abs(res)) < dbm_validate_threshold)
995 TYPE(
dbm_type),
INTENT(INOUT) :: matrix
999 FUNCTION dbm_maxabs_c(matrix) &
1000 BIND(C, name="dbm_maxabs")
1001 IMPORT :: c_ptr, c_double
1002 TYPE(c_ptr),
VALUE :: matrix
1003 REAL(c_double) :: dbm_maxabs_c
1004 END FUNCTION dbm_maxabs_c
1008 res = dbm_maxabs_c(matrix%c_ptr)
1010#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1011 cpassert(abs(res - dbcsr_maxabs(matrix%dbcsr))/max(1.0_dp, abs(res)) < dbm_validate_threshold)
1022 TYPE(
dbm_type),
INTENT(IN) :: matrix
1023 CHARACTER(len=default_string_length) :: res
1025 CHARACTER(LEN=1, KIND=C_CHAR),
DIMENSION(:), &
1028 TYPE(c_ptr) :: name_c
1030 FUNCTION dbm_get_name_c(matrix)
BIND(C, name="dbm_get_name")
1032 TYPE(c_ptr),
VALUE :: matrix
1033 TYPE(c_ptr) :: dbm_get_name_c
1034 END FUNCTION dbm_get_name_c
1037 name_c = dbm_get_name_c(matrix%c_ptr)
1043 IF (name_f(i) == c_null_char)
EXIT
1044 res(i:i) = name_f(i)
1056 TYPE(
dbm_type),
INTENT(IN) :: matrix
1060 PURE FUNCTION dbm_get_nze_c(matrix) &
1061 BIND(C, name="dbm_get_nze")
1062 IMPORT :: c_ptr, c_int
1063 TYPE(c_ptr),
VALUE,
INTENT(IN) :: matrix
1064 INTEGER(C_INT) :: dbm_get_nze_c
1065 END FUNCTION dbm_get_nze_c
1068 res = dbm_get_nze_c(matrix%c_ptr)
1079 TYPE(
dbm_type),
INTENT(IN) :: matrix
1083 PURE FUNCTION dbm_get_num_blocks_c(matrix) &
1084 BIND(C, name="dbm_get_num_blocks")
1085 IMPORT :: c_ptr, c_int
1086 TYPE(c_ptr),
VALUE,
INTENT(IN) :: matrix
1087 INTEGER(C_INT) :: dbm_get_num_blocks_c
1088 END FUNCTION dbm_get_num_blocks_c
1091 res = dbm_get_num_blocks_c(matrix%c_ptr)
1102 TYPE(
dbm_type),
INTENT(IN) :: matrix
1103 INTEGER,
CONTIGUOUS,
DIMENSION(:),
POINTER :: res
1106 TYPE(c_ptr) :: row_sizes
1108 SUBROUTINE dbm_get_row_sizes_c(matrix, nrows, row_sizes) &
1109 BIND(C, name="dbm_get_row_sizes")
1110 IMPORT :: c_ptr, c_int
1111 TYPE(c_ptr),
VALUE :: matrix
1112 INTEGER(C_INT) :: nrows
1113 TYPE(c_ptr) :: row_sizes
1114 END SUBROUTINE dbm_get_row_sizes_c
1117 CALL dbm_get_row_sizes_c(matrix%c_ptr, nrows, row_sizes)
1118 CALL c_f_pointer(row_sizes, res, shape=(/nrows/))
1129 TYPE(
dbm_type),
INTENT(IN) :: matrix
1130 INTEGER,
CONTIGUOUS,
DIMENSION(:),
POINTER :: res
1133 TYPE(c_ptr) :: col_sizes
1135 SUBROUTINE dbm_get_col_sizes_c(matrix, ncols, col_sizes) &
1136 BIND(C, name="dbm_get_col_sizes")
1137 IMPORT :: c_ptr, c_int
1138 TYPE(c_ptr),
VALUE :: matrix
1139 INTEGER(C_INT) :: ncols
1140 TYPE(c_ptr) :: col_sizes
1141 END SUBROUTINE dbm_get_col_sizes_c
1144 CALL dbm_get_col_sizes_c(matrix%c_ptr, ncols, col_sizes)
1145 CALL c_f_pointer(col_sizes, res, shape=(/ncols/))
1157 TYPE(
dbm_type),
INTENT(IN) :: matrix
1158 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: local_rows
1160 INTEGER :: nlocal_rows
1161 INTEGER,
DIMENSION(:),
POINTER :: local_rows_dbcsr, local_rows_ptr
1162 TYPE(c_ptr) :: local_rows_c
1164 SUBROUTINE dbm_get_local_rows_c(matrix, nlocal_rows, local_rows) &
1165 BIND(C, name="dbm_get_local_rows")
1166 IMPORT :: c_ptr, c_int
1167 TYPE(c_ptr),
VALUE :: matrix
1168 INTEGER(C_INT) :: nlocal_rows
1169 TYPE(c_ptr) :: local_rows
1170 END SUBROUTINE dbm_get_local_rows_c
1173 CALL dbm_get_local_rows_c(matrix%c_ptr, nlocal_rows, local_rows_c)
1174 CALL c_f_pointer(local_rows_c, local_rows_ptr, shape=(/nlocal_rows/))
1175 ALLOCATE (local_rows(nlocal_rows))
1176 local_rows(:) = local_rows_ptr(:) + 1
1178#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1179 CALL dbcsr_get_info(matrix%dbcsr, local_rows=local_rows_dbcsr)
1180 cpassert(all(local_rows == local_rows_dbcsr))
1182 mark_used(local_rows_dbcsr)
1194 TYPE(
dbm_type),
INTENT(IN) :: matrix
1195 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: local_cols
1197 INTEGER :: nlocal_cols
1198 INTEGER,
DIMENSION(:),
POINTER :: local_cols_dbcsr, local_cols_ptr
1199 TYPE(c_ptr) :: local_cols_c
1201 SUBROUTINE dbm_get_local_cols_c(matrix, nlocal_cols, local_cols) &
1202 BIND(C, name="dbm_get_local_cols")
1203 IMPORT :: c_ptr, c_int
1204 TYPE(c_ptr),
VALUE :: matrix
1205 INTEGER(C_INT) :: nlocal_cols
1206 TYPE(c_ptr) :: local_cols
1207 END SUBROUTINE dbm_get_local_cols_c
1210 CALL dbm_get_local_cols_c(matrix%c_ptr, nlocal_cols, local_cols_c)
1211 CALL c_f_pointer(local_cols_c, local_cols_ptr, shape=(/nlocal_cols/))
1212 ALLOCATE (local_cols(nlocal_cols))
1213 local_cols(:) = local_cols_ptr(:) + 1
1215#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1216 CALL dbcsr_get_info(matrix%dbcsr, local_cols=local_cols_dbcsr)
1217 cpassert(all(local_cols == local_cols_dbcsr))
1219 mark_used(local_cols_dbcsr)
1232 TYPE(
dbm_type),
INTENT(IN) :: matrix
1233 INTEGER,
INTENT(IN) :: row, column
1234 INTEGER,
INTENT(OUT) :: processor
1236 INTEGER :: processor_dbcsr
1238 PURE FUNCTION dbm_get_stored_coordinates_c(matrix, row, col) &
1239 BIND(C, name="dbm_get_stored_coordinates")
1240 IMPORT :: c_ptr, c_int
1241 TYPE(c_ptr),
VALUE,
INTENT(IN) :: matrix
1242 INTEGER(C_INT),
VALUE,
INTENT(IN) :: row
1243 INTEGER(C_INT),
VALUE,
INTENT(IN) :: col
1244 INTEGER(C_INT) :: dbm_get_stored_coordinates_c
1245 END FUNCTION dbm_get_stored_coordinates_c
1248 processor = dbm_get_stored_coordinates_c(matrix%c_ptr, row=row - 1, col=column - 1)
1250#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1251 CALL dbcsr_get_stored_coordinates(matrix%dbcsr, row, column, processor_dbcsr)
1252 cpassert(processor == processor_dbcsr)
1254 mark_used(processor_dbcsr)
1265 TYPE(
dbm_type),
INTENT(IN) :: matrix
1269 FUNCTION dbm_get_distribution_c(matrix)
BIND(C, name="dbm_get_distribution")
1271 TYPE(c_ptr),
VALUE :: matrix
1272 TYPE(c_ptr) :: dbm_get_distribution_c
1273 END FUNCTION dbm_get_distribution_c
1276 res%c_ptr = dbm_get_distribution_c(matrix%c_ptr)
1278#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1279 CALL dbcsr_get_info(matrix%dbcsr, distribution=res%dbcsr)
1296 INTEGER,
CONTIGUOUS,
DIMENSION(:),
INTENT(IN), &
1297 POINTER :: row_dist_block, col_dist_block
1300 SUBROUTINE dbm_distribution_new_c(dist, fortran_comm, nrows, ncols, row_dist, col_dist) &
1301 BIND(C, name="dbm_distribution_new")
1302 IMPORT :: c_ptr, c_char, c_int
1304 INTEGER(kind=C_INT),
VALUE :: fortran_comm
1305 INTEGER(kind=C_INT),
VALUE :: nrows
1306 INTEGER(kind=C_INT),
VALUE :: ncols
1307 INTEGER(kind=C_INT),
DIMENSION(*) :: row_dist
1308 INTEGER(kind=C_INT),
DIMENSION(*) :: col_dist
1309 END SUBROUTINE dbm_distribution_new_c
1312 cpassert(.NOT. c_associated(dist%c_ptr))
1313 CALL dbm_distribution_new_c(dist=dist%c_ptr, &
1314 fortran_comm=mp_comm%get_handle(), &
1315 nrows=
SIZE(row_dist_block), &
1316 ncols=
SIZE(col_dist_block), &
1317 row_dist=row_dist_block, &
1318 col_dist=col_dist_block)
1319 cpassert(c_associated(dist%c_ptr))
1321#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1322 CALL dbcsr_distribution_new_wrapper(dist, mp_comm, row_dist_block, col_dist_block)
1334 SUBROUTINE dbcsr_distribution_new_wrapper(dist, mp_comm, row_dist_block, col_dist_block)
1337 INTEGER,
CONTIGUOUS,
DIMENSION(:),
INTENT(IN), &
1338 POINTER :: row_dist_block, col_dist_block
1340#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1341 INTEGER :: mynode, numnodes, pcol, prow
1342 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: pgrid
1343 INTEGER,
DIMENSION(2) :: coord, mycoord, npdims
1344 TYPE(dbcsr_mp_obj) :: mp_env
1347 CALL mp_comm%get_info_cart(npdims, mycoord)
1348 CALL mp_comm%get_size(numnodes)
1349 CALL mp_comm%get_rank(mynode)
1350 ALLOCATE (pgrid(0:npdims(1) - 1, 0:npdims(2) - 1))
1351 DO prow = 0, npdims(1) - 1
1352 DO pcol = 0, npdims(2) - 1
1353 coord = (/prow, pcol/)
1354 CALL mp_comm%rank_cart(coord, pgrid(prow, pcol))
1357 cpassert(mynode == pgrid(mycoord(1), mycoord(2)))
1359 CALL dbcsr_mp_new(mp_env, mp_comm%get_handle(), pgrid, mynode, numnodes, mycoord(1), mycoord(2))
1360 CALL dbcsr_distribution_new(dist=dist%dbcsr, mp_env=mp_env, &
1361 row_dist_block=row_dist_block, col_dist_block=col_dist_block)
1362 CALL dbcsr_mp_release(mp_env)
1366 mark_used(row_dist_block)
1367 mark_used(col_dist_block)
1369 END SUBROUTINE dbcsr_distribution_new_wrapper
1380 SUBROUTINE dbm_distribution_hold_c(dist) &
1381 BIND(C, name="dbm_distribution_hold")
1383 TYPE(c_ptr),
VALUE :: dist
1384 END SUBROUTINE dbm_distribution_hold_c
1387 CALL dbm_distribution_hold_c(dist%c_ptr)
1389#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1390 CALL dbcsr_distribution_hold(dist%dbcsr)
1403 SUBROUTINE dbm_distribution_release_c(dist) &
1404 BIND(C, name="dbm_distribution_release")
1406 TYPE(c_ptr),
VALUE :: dist
1407 END SUBROUTINE dbm_distribution_release_c
1410 CALL dbm_distribution_release_c(dist%c_ptr)
1412#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1413 CALL dbcsr_distribution_release(dist%dbcsr)
1425 INTEGER,
CONTIGUOUS,
DIMENSION(:),
POINTER :: res
1428 TYPE(c_ptr) :: row_dist
1430 SUBROUTINE dbm_distribution_row_dist_c(dist, nrows, row_dist) &
1431 BIND(C, name="dbm_distribution_row_dist")
1432 IMPORT :: c_ptr, c_int
1433 TYPE(c_ptr),
VALUE :: dist
1434 INTEGER(C_INT) :: nrows
1435 TYPE(c_ptr) :: row_dist
1436 END SUBROUTINE dbm_distribution_row_dist_c
1439 CALL dbm_distribution_row_dist_c(dist%c_ptr, nrows, row_dist)
1440 CALL c_f_pointer(row_dist, res, shape=(/nrows/))
1442#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1443 cpassert(all(res == dbcsr_distribution_row_dist(dist%dbcsr)))
1455 INTEGER,
CONTIGUOUS,
DIMENSION(:),
POINTER :: res
1458 TYPE(c_ptr) :: col_dist
1460 SUBROUTINE dbm_distribution_col_dist_c(dist, ncols, col_dist) &
1461 BIND(C, name="dbm_distribution_col_dist")
1462 IMPORT :: c_ptr, c_int
1463 TYPE(c_ptr),
VALUE :: dist
1464 INTEGER(C_INT) :: ncols
1465 TYPE(c_ptr) :: col_dist
1466 END SUBROUTINE dbm_distribution_col_dist_c
1469 CALL dbm_distribution_col_dist_c(dist%c_ptr, ncols, col_dist)
1470 CALL c_f_pointer(col_dist, res, shape=(/ncols/))
1472#if defined(DBM_VALIDATE_AGAINST_DBCSR)
1473 cpassert(all(res == dbcsr_distribution_col_dist(dist%dbcsr)))
1483 SUBROUTINE dbm_library_init_c()
BIND(C, name="dbm_library_init")
1484 END SUBROUTINE dbm_library_init_c
1487 CALL dbm_library_init_c()
1497 SUBROUTINE dbm_library_finalize_c()
BIND(C, name="dbm_library_finalize")
1498 END SUBROUTINE dbm_library_finalize_c
1501 CALL dbm_library_finalize_c()
1513 INTEGER,
INTENT(IN) :: output_unit
1516 SUBROUTINE dbm_library_print_stats_c(mpi_comm, print_func, output_unit) &
1517 BIND(C, name="dbm_library_print_stats")
1518 IMPORT :: c_funptr, c_int
1519 INTEGER(KIND=C_INT),
VALUE :: mpi_comm
1520 TYPE(c_funptr),
VALUE :: print_func
1521 INTEGER(KIND=C_INT),
VALUE :: output_unit
1522 END SUBROUTINE dbm_library_print_stats_c
1526 CALL dbm_library_print_stats_c(mpi_comm=mpi_comm%get_handle(), &
1527 print_func=c_funloc(print_func), &
1528 output_unit=output_unit)
1539 SUBROUTINE print_func(msg, msglen, output_unit)
BIND(C, name="dbm_api_print_func")
1540 CHARACTER(KIND=C_CHAR),
INTENT(IN) :: msg(*)
1541 INTEGER(KIND=C_INT),
INTENT(IN),
VALUE :: msglen, output_unit
1543 IF (output_unit <= 0)
RETURN
1544 WRITE (output_unit, fmt=
"(100A)", advance=
"NO") msg(1:msglen)
1545 END SUBROUTINE print_func
subroutine, public dbm_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, retain_sparsity, filter_eps, flop)
Computes matrix product: matrix_c = alpha * matrix_a * matrix_b + beta * matrix_c.
subroutine, public dbm_redistribute(matrix, redist)
Copies content of matrix_b into matrix_a. Matrices may have different distributions.
subroutine, public dbm_zero(matrix)
Sets all blocks in the given matrix to zero.
subroutine, public dbm_clear(matrix)
Remove all blocks from given matrix, but does not release the underlying memory.
real(kind=dp) function, public dbm_maxabs(matrix)
Returns the absolute value of the larges element of the entire given matrix.
subroutine, public dbm_create_from_template(matrix, name, template)
Creates a new matrix from given template, reusing dist and row/col_block_sizes.
subroutine validate(matrix)
Dummy for when DBM_VALIDATE_AGAINST_DBCSR is not defined.
pure integer function, public dbm_get_nze(matrix)
Returns the number of local Non-Zero Elements of the given matrix.
subroutine, public dbm_get_local_cols(matrix, local_cols)
Returns the local column block sizes of the given matrix.
subroutine, public dbm_scale(matrix, alpha)
Multiplies all entries in the given matrix by the given factor alpha.
subroutine, public dbm_distribution_release(dist)
Decreases the reference counter of the given distribution.
subroutine, public dbm_library_init()
Initialize DBM library.
subroutine, public dbm_iterator_next_block(iterator, row, column, block, row_size, col_size)
Returns the next block from the given iterator.
subroutine, public dbm_filter(matrix, eps)
Removes all blocks from the given matrix whose block norm is below the given threshold....
integer function, public dbm_iterator_num_blocks(iterator)
Returns number of blocks the iterator will provide to calling thread.
subroutine, public dbm_get_stored_coordinates(matrix, row, column, processor)
Returns the MPI rank on which the given block should be stored.
type(dbm_distribution_obj) function, public dbm_get_distribution(matrix)
Returns the distribution of the given matrix.
subroutine, public dbm_create(matrix, name, dist, row_block_sizes, col_block_sizes)
Creates a new matrix.
integer function, dimension(:), pointer, contiguous, public dbm_get_row_block_sizes(matrix)
Returns the row block sizes of the given matrix.
logical function, public dbm_iterator_blocks_left(iterator)
Tests whether the given iterator has any block left.
integer function, dimension(:), pointer, contiguous, public dbm_distribution_col_dist(dist)
Returns the columns of the given distribution.
subroutine, public dbm_reserve_blocks(matrix, rows, cols)
Adds given list of blocks efficiently. The blocks will be filled with zeros.
subroutine, public dbm_library_finalize()
Finalize DBM library.
subroutine, public dbm_iterator_stop(iterator)
Releases the given iterator.
subroutine, public dbm_get_local_rows(matrix, local_rows)
Returns the local row block sizes of the given matrix.
subroutine, public dbm_put_block(matrix, row, col, block, summation)
Adds a block to given matrix. This routine is thread-safe. If block already exist then it gets overwr...
character(len=default_string_length) function, public dbm_get_name(matrix)
Returns the name of the matrix of the given matrix.
real(kind=dp) function, public dbm_checksum(matrix)
Computes a checksum of the given matrix.
subroutine, public dbm_add(matrix_a, matrix_b)
Adds matrix_b to matrix_a.
subroutine, public dbm_finalize(matrix)
Needed to be called for DBCSR after blocks where inserted. For DBM it's a no-opt.
subroutine, public dbm_iterator_start(iterator, matrix)
Creates an iterator for the blocks of the given matrix. The iteration order is not stable.
pure integer function, public dbm_get_num_blocks(matrix)
Returns the number of local blocks of the given matrix.
subroutine, public dbm_library_print_stats(mpi_comm, output_unit)
Print DBM library statistics.
subroutine, public dbm_copy(matrix_a, matrix_b)
Copies content of matrix_b into matrix_a. Matrices must have the same row/col block sizes and distrib...
subroutine, public dbm_distribution_hold(dist)
Increases the reference counter of the given distribution.
subroutine, public dbm_release(matrix)
Releases a matrix and all its ressources.
integer function, dimension(:), pointer, contiguous, public dbm_get_col_block_sizes(matrix)
Returns the column block sizes of the given matrix.
integer function, dimension(:), pointer, contiguous, public dbm_distribution_row_dist(dist)
Returns the rows of the given distribution.
subroutine, public dbm_distribution_new(dist, mp_comm, row_dist_block, col_dist_block)
Creates a new two dimensional distribution.
subroutine, public dbm_get_block_p(matrix, row, col, block, row_size, col_size)
Looks up a block from given matrics. This routine is thread-safe. If the block is not found then a nu...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public default_string_length
Interface to the message passing library MPI.