16 USE dbcsr_api,
ONLY: dbcsr_copy, &
18 dbcsr_distribution_get, &
19 dbcsr_distribution_new, &
20 dbcsr_distribution_release, &
21 dbcsr_distribution_type, &
23 dbcsr_iterator_blocks_left, &
24 dbcsr_iterator_next_block, &
25 dbcsr_iterator_start, &
26 dbcsr_iterator_stop, &
27 dbcsr_iterator_type, &
29 dbcsr_reserve_all_blocks, &
30 dbcsr_set, dbcsr_get_data_p, &
32 dbcsr_type_antisymmetric, &
33 dbcsr_type_complex_8, &
34 dbcsr_type_complex_8, &
35 dbcsr_type_no_symmetry, &
43 #include "../base/base_uses.f90"
51 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dbcsr_vector_operations'
62 TYPE(ele_type),
DIMENSION(:),
POINTER :: table => null()
66 END TYPE hash_table_type
72 REAL(real_8),
DIMENSION(:, :),
POINTER :: ptr => null()
73 INTEGER :: assigned_thread = -1
76 COMPLEX(real_8),
DIMENSION(:, :),
POINTER :: ptr => null()
77 INTEGER :: assigned_thread = -1
80 TYPE fast_vec_access_type
81 TYPE(hash_table_type) :: hash_table = hash_table_type()
82 TYPE(block_ptr_d),
DIMENSION(:),
ALLOCATABLE :: blk_map_d
83 TYPE(block_ptr_z),
DIMENSION(:),
ALLOCATABLE :: blk_map_z
86 PUBLIC :: dbcsr_matrix_colvec_multiply, &
92 INTERFACE dbcsr_matrix_colvec_multiply
93 MODULE PROCEDURE dbcsr_matrix_colvec_multiply_d
94 MODULE PROCEDURE dbcsr_matrix_colvec_multiply_z
109 TYPE(dbcsr_type) :: dbcsr_vec, matrix
112 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_col_vec_from_matrix'
114 INTEGER :: handle, npcols, data_type
115 INTEGER,
DIMENSION(:),
POINTER :: row_blk_size, col_blk_size, row_dist, col_dist
116 TYPE(dbcsr_distribution_type) :: dist_col_vec, dist
118 CALL timeset(routinen, handle)
120 CALL dbcsr_get_info(matrix, data_type=data_type, row_blk_size=row_blk_size, distribution=dist)
121 CALL dbcsr_distribution_get(dist, npcols=npcols, row_dist=row_dist)
123 ALLOCATE (col_dist(1), col_blk_size(1))
125 col_blk_size(1) = ncol
126 CALL dbcsr_distribution_new(dist_col_vec, template=dist, row_dist=row_dist, col_dist=col_dist)
128 CALL dbcsr_create(dbcsr_vec,
"D", dist_col_vec, &
129 matrix_type=dbcsr_type_no_symmetry, &
130 row_blk_size=row_blk_size, &
131 col_blk_size=col_blk_size, &
132 nze=0, data_type=data_type)
133 CALL dbcsr_reserve_all_blocks(dbcsr_vec)
135 CALL dbcsr_distribution_release(dist_col_vec)
136 DEALLOCATE (col_dist, col_blk_size)
137 CALL timestop(handle)
151 TYPE(dbcsr_type) :: dbcsr_vec, matrix
154 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_row_vec_from_matrix'
156 INTEGER :: handle, nprows, data_type
157 INTEGER,
DIMENSION(:),
POINTER :: row_blk_size, col_blk_size, row_dist, col_dist
158 TYPE(dbcsr_distribution_type) :: dist_row_vec, dist
160 CALL timeset(routinen, handle)
162 CALL dbcsr_get_info(matrix, data_type=data_type, col_blk_size=col_blk_size, distribution=dist)
163 CALL dbcsr_distribution_get(dist, nprows=nprows, col_dist=col_dist)
165 ALLOCATE (row_dist(1), row_blk_size(1))
167 row_blk_size(1) = nrow
168 CALL dbcsr_distribution_new(dist_row_vec, template=dist, row_dist=row_dist, col_dist=col_dist)
170 CALL dbcsr_create(dbcsr_vec,
"D", dist_row_vec, &
171 matrix_type=dbcsr_type_no_symmetry, &
172 row_blk_size=row_blk_size, &
173 col_blk_size=col_blk_size, &
174 nze=0, data_type=data_type)
175 CALL dbcsr_reserve_all_blocks(dbcsr_vec)
177 CALL dbcsr_distribution_release(dist_row_vec)
178 DEALLOCATE (row_dist, row_blk_size)
179 CALL timestop(handle)
193 TYPE(dbcsr_type) :: dbcsr_vec, matrix
196 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_replicated_col_vec_from_matrix'
198 INTEGER :: handle, npcols, data_type, i
199 INTEGER,
DIMENSION(:),
POINTER :: row_blk_size, col_blk_size, row_dist, col_dist
200 TYPE(dbcsr_distribution_type) :: dist_col_vec, dist
201 CALL timeset(routinen, handle)
203 CALL dbcsr_get_info(matrix, data_type=data_type, row_blk_size=row_blk_size, distribution=dist)
204 CALL dbcsr_distribution_get(dist, npcols=npcols, row_dist=row_dist)
206 ALLOCATE (col_dist(npcols), col_blk_size(npcols))
207 col_blk_size(:) = ncol
211 CALL dbcsr_distribution_new(dist_col_vec, template=dist, row_dist=row_dist, col_dist=col_dist)
213 CALL dbcsr_create(dbcsr_vec,
"D", dist_col_vec, &
214 matrix_type=dbcsr_type_no_symmetry, &
215 row_blk_size=row_blk_size, &
216 col_blk_size=col_blk_size, &
217 nze=0, data_type=data_type)
218 CALL dbcsr_reserve_all_blocks(dbcsr_vec)
220 CALL dbcsr_distribution_release(dist_col_vec)
221 DEALLOCATE (col_dist, col_blk_size)
222 CALL timestop(handle)
236 TYPE(dbcsr_type) :: dbcsr_vec
237 TYPE(dbcsr_type) :: matrix
240 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_replicated_row_vec_from_matrix'
242 INTEGER :: handle, i, nprows, data_type
243 INTEGER,
DIMENSION(:),
POINTER :: row_dist, col_dist, row_blk_size, col_blk_size
244 TYPE(dbcsr_distribution_type) :: dist_row_vec, dist
246 CALL timeset(routinen, handle)
248 CALL dbcsr_get_info(matrix, distribution=dist, col_blk_size=col_blk_size, data_type=data_type)
249 CALL dbcsr_distribution_get(dist, nprows=nprows, col_dist=col_dist)
251 ALLOCATE (row_dist(nprows), row_blk_size(nprows))
252 row_blk_size(:) = nrow
256 CALL dbcsr_distribution_new(dist_row_vec, template=dist, row_dist=row_dist, col_dist=col_dist)
258 CALL dbcsr_create(dbcsr_vec,
"D", dist_row_vec, dbcsr_type_no_symmetry, &
259 row_blk_size=row_blk_size, col_blk_size=col_blk_size, &
260 nze=0, data_type=data_type)
261 CALL dbcsr_reserve_all_blocks(dbcsr_vec)
263 CALL dbcsr_distribution_release(dist_row_vec)
264 DEALLOCATE (row_dist, row_blk_size)
265 CALL timestop(handle)
274 SUBROUTINE create_fast_col_vec_access(vec, fast_vec_access)
275 TYPE(dbcsr_type) :: vec
276 TYPE(fast_vec_access_type) :: fast_vec_access
278 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_fast_col_vec_access'
280 INTEGER :: handle, data_type
282 CALL timeset(routinen, handle)
284 CALL dbcsr_get_info(vec, data_type=data_type)
286 SELECT CASE (data_type)
287 CASE (dbcsr_type_real_8)
288 CALL create_fast_col_vec_access_d(vec, fast_vec_access)
289 CASE (dbcsr_type_complex_8)
290 CALL create_fast_col_vec_access_z(vec, fast_vec_access)
293 CALL timestop(handle)
295 END SUBROUTINE create_fast_col_vec_access
302 SUBROUTINE create_fast_row_vec_access(vec, fast_vec_access)
303 TYPE(dbcsr_type) :: vec
304 TYPE(fast_vec_access_type) :: fast_vec_access
306 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_fast_row_vec_access'
308 INTEGER :: handle, data_type
310 CALL timeset(routinen, handle)
312 CALL dbcsr_get_info(vec, data_type=data_type)
314 SELECT CASE (data_type)
315 CASE (dbcsr_type_real_8)
316 CALL create_fast_row_vec_access_d(vec, fast_vec_access)
317 CASE (dbcsr_type_complex_8)
318 CALL create_fast_row_vec_access_z(vec, fast_vec_access)
321 CALL timestop(handle)
323 END SUBROUTINE create_fast_row_vec_access
329 SUBROUTINE release_fast_vec_access(fast_vec_access)
330 TYPE(fast_vec_access_type) :: fast_vec_access
332 CHARACTER(LEN=*),
PARAMETER :: routinen =
'release_fast_vec_access'
336 CALL timeset(routinen, handle)
338 CALL hash_table_release(fast_vec_access%hash_table)
339 IF (
ALLOCATED(fast_vec_access%blk_map_d))
DEALLOCATE (fast_vec_access%blk_map_d)
340 IF (
ALLOCATED(fast_vec_access%blk_map_z))
DEALLOCATE (fast_vec_access%blk_map_z)
342 CALL timestop(handle)
344 END SUBROUTINE release_fast_vec_access
359 FUNCTION matching_prime(i)
RESULT(res)
360 INTEGER,
INTENT(IN) :: i
369 IF (mod(res, j) == 0)
THEN
383 SUBROUTINE hash_table_create(hash_table, table_size)
384 TYPE(hash_table_type) :: hash_table
385 INTEGER,
INTENT(IN) :: table_size
392 DO WHILE (2**j - 1 < table_size)
395 hash_table%nmax = 2**j - 1
396 hash_table%prime = matching_prime(hash_table%nmax)
398 ALLOCATE (hash_table%table(0:hash_table%nmax))
399 END SUBROUTINE hash_table_create
405 SUBROUTINE hash_table_release(hash_table)
406 TYPE(hash_table_type) :: hash_table
410 DEALLOCATE (hash_table%table)
412 END SUBROUTINE hash_table_release
420 RECURSIVE SUBROUTINE hash_table_add(hash_table, c, p)
421 TYPE(hash_table_type),
INTENT(INOUT) :: hash_table
422 INTEGER,
INTENT(IN) :: c, p
424 REAL(kind=
real_8),
PARAMETER :: hash_table_expand = 1.5_real_8, &
425 inv_hash_table_fill = 2.5_real_8
428 TYPE(ele_type),
ALLOCATABLE, &
429 DIMENSION(:) :: tmp_hash
433 IF (hash_table%nele*inv_hash_table_fill > hash_table%nmax)
THEN
434 ALLOCATE (tmp_hash(lbound(hash_table%table, 1):ubound(hash_table%table, 1)))
435 tmp_hash(:) = hash_table%table
436 CALL hash_table_release(hash_table)
437 CALL hash_table_create(hash_table, int((ubound(tmp_hash, 1) + 8)*hash_table_expand))
438 DO i = lbound(tmp_hash, 1), ubound(tmp_hash, 1)
439 IF (tmp_hash(i)%c .NE. 0)
THEN
440 CALL hash_table_add(hash_table, tmp_hash(i)%c, tmp_hash(i)%p)
443 DEALLOCATE (tmp_hash)
446 hash_table%nele = hash_table%nele + 1
447 i = iand(c*hash_table%prime, hash_table%nmax)
449 DO j = i, hash_table%nmax
450 IF (hash_table%table(j)%c == 0 .OR. hash_table%table(j)%c == c)
THEN
451 hash_table%table(j)%c = c
452 hash_table%table(j)%p = p
457 IF (hash_table%table(j)%c == 0 .OR. hash_table%table(j)%c == c)
THEN
458 hash_table%table(j)%c = c
459 hash_table%table(j)%p = p
464 END SUBROUTINE hash_table_add
472 PURE FUNCTION hash_table_get(hash_table, c)
RESULT(p)
473 TYPE(hash_table_type),
INTENT(IN) :: hash_table
474 INTEGER,
INTENT(IN) :: c
479 i = iand(c*hash_table%prime, hash_table%nmax)
482 IF (hash_table%table(i)%c == c)
THEN
483 p = hash_table%table(i)%p
487 DO j = i, hash_table%nmax
488 IF (hash_table%table(j)%c == 0 .OR. hash_table%table(j)%c == c)
THEN
489 p = hash_table%table(j)%p
494 IF (hash_table%table(j)%c == 0 .OR. hash_table%table(j)%c == c)
THEN
495 p = hash_table%table(j)%p
503 END FUNCTION hash_table_get
520 SUBROUTINE dbcsr_matrix_colvec_multiply_d (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
521 TYPE(dbcsr_type) :: matrix, vec_in, vec_out
522 REAL(kind=
real_8) :: alpha, beta
523 TYPE(dbcsr_type) :: work_row, work_col
525 CHARACTER :: matrix_type
527 CALL dbcsr_get_info(matrix, matrix_type=matrix_type)
529 SELECT CASE (matrix_type)
530 CASE (dbcsr_type_no_symmetry)
531 CALL dbcsr_matrix_vector_mult_d (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
532 CASE (dbcsr_type_symmetric)
533 CALL dbcsr_sym_matrix_vector_mult_d (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
534 CASE (dbcsr_type_antisymmetric)
536 cpabort(
"NYI, antisymmetric matrix not permitted")
538 cpabort(
"Unknown matrix type, ...")
541 END SUBROUTINE dbcsr_matrix_colvec_multiply_d
553 SUBROUTINE dbcsr_matrix_vector_mult_d (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
554 TYPE(dbcsr_type) :: matrix, vec_in, vec_out
555 REAL(kind=
real_8) :: alpha, beta
556 TYPE(dbcsr_type) :: work_row, work_col
558 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_matrix_vector_mult'
560 INTEGER :: col, mypcol, &
561 myprow, prow_handle, &
564 handle, handle1, ithread
565 TYPE(mp_comm_type) :: prow_group
566 REAL(kind=
real_8),
DIMENSION(:),
POINTER :: data_vec
567 REAL(kind=
real_8),
DIMENSION(:, :),
POINTER :: data_d, vec_res
568 TYPE(dbcsr_distribution_type) :: dist
569 TYPE(dbcsr_iterator_type) :: iter
570 TYPE(fast_vec_access_type) :: fast_vec_row, fast_vec_col
571 INTEGER :: prow, pcol
573 CALL timeset(routinen, handle)
577 CALL dbcsr_get_info(matrix, distribution=dist)
578 CALL dbcsr_distribution_get(dist, prow_group=prow_handle, myprow=myprow, mypcol=mypcol)
580 CALL prow_group%set_handle(prow_handle)
582 CALL create_fast_row_vec_access(work_row, fast_vec_row)
583 CALL create_fast_col_vec_access(work_col, fast_vec_col)
586 CALL dbcsr_col_vec_to_rep_row_d (vec_in, work_col, work_row, fast_vec_col)
589 CALL dbcsr_set(work_col, 0.0_real_8)
593 CALL timeset(routinen//
"_local_mm", handle1)
598 CALL dbcsr_iterator_start(iter, matrix, shared=.false.)
599 DO WHILE (dbcsr_iterator_blocks_left(iter))
600 CALL dbcsr_iterator_next_block(iter, row, col, data_d)
601 prow = hash_table_get(fast_vec_col%hash_table, row)
602 IF (fast_vec_col%blk_map_d (prow)%assigned_thread .NE. ithread) cycle
603 pcol = hash_table_get(fast_vec_row%hash_table, col)
604 IF (
SIZE(fast_vec_col%blk_map_d (prow)%ptr, 1) .EQ. 0 .OR. &
605 SIZE(fast_vec_col%blk_map_d (prow)%ptr, 2) .EQ. 0 .OR. &
606 SIZE(data_d, 2) .EQ. 0) cycle
607 CALL dgemm(
'N',
'T',
SIZE(fast_vec_col%blk_map_d (prow)%ptr, 1), &
608 SIZE(fast_vec_col%blk_map_d (prow)%ptr, 2), &
612 SIZE(fast_vec_col%blk_map_d (prow)%ptr, 1), &
613 fast_vec_row%blk_map_d (pcol)%ptr, &
614 SIZE(fast_vec_col%blk_map_d (prow)%ptr, 2), &
616 fast_vec_col%blk_map_d (prow)%ptr, &
617 SIZE(fast_vec_col%blk_map_d (prow)%ptr, 1))
619 CALL dbcsr_iterator_stop(iter)
622 CALL timestop(handle1)
625 data_vec => dbcsr_get_data_p(work_col, select_data_type=0.0_real_8)
626 CALL dbcsr_get_info(matrix=work_col, nfullrows_local=nrows, nfullcols_local=ncols)
627 CALL prow_group%sum(data_vec(1:nrows*ncols))
631 CALL dbcsr_iterator_start(iter, vec_out)
632 DO WHILE (dbcsr_iterator_blocks_left(iter))
633 CALL dbcsr_iterator_next_block(iter, row, col, vec_res)
634 prow = hash_table_get(fast_vec_col%hash_table, row)
635 IF (
ASSOCIATED(fast_vec_col%blk_map_d (prow)%ptr))
THEN
636 vec_res(:, :) = beta*vec_res(:, :) + alpha*fast_vec_col%blk_map_d (prow)%ptr(:, :)
638 vec_res(:, :) = beta*vec_res(:, :)
641 CALL dbcsr_iterator_stop(iter)
643 CALL release_fast_vec_access(fast_vec_row)
644 CALL release_fast_vec_access(fast_vec_col)
646 CALL timestop(handle)
648 END SUBROUTINE dbcsr_matrix_vector_mult_d
661 SUBROUTINE dbcsr_matrixt_vector_mult_d (matrix, vec_in, vec_out, alpha, beta, work_row, work_col, skip_diag)
662 TYPE(dbcsr_type) :: matrix, vec_in, vec_out
663 REAL(kind=
real_8) :: alpha, beta
664 TYPE(dbcsr_type) :: work_row, work_col
667 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_matrixT_vector_mult'
669 INTEGER :: col, col_size, mypcol, &
670 myprow, pcol_handle, prow_handle, &
673 handle, handle1, ithread
674 TYPE(mp_comm_type) :: pcol_group, prow_group
675 REAL(kind=
real_8),
DIMENSION(:),
POINTER :: data_vec
676 REAL(kind=
real_8),
DIMENSION(:, :),
POINTER :: data_d, vec_bl, vec_res
677 TYPE(dbcsr_distribution_type) :: dist
678 TYPE(dbcsr_iterator_type) :: iter
680 TYPE(fast_vec_access_type) :: fast_vec_row, fast_vec_col
681 INTEGER :: prow, pcol
683 CALL timeset(routinen, handle)
687 CALL dbcsr_get_info(matrix, distribution=dist)
688 CALL dbcsr_distribution_get(dist, prow_group=prow_handle, pcol_group=pcol_handle, myprow=myprow, mypcol=mypcol)
690 CALL prow_group%set_handle(prow_handle)
691 CALL pcol_group%set_handle(pcol_handle)
693 CALL create_fast_row_vec_access(work_row, fast_vec_row)
694 CALL create_fast_col_vec_access(work_col, fast_vec_col)
697 CALL dbcsr_set(work_row, 0.0_real_8)
700 CALL dbcsr_iterator_start(iter, vec_in)
701 DO WHILE (dbcsr_iterator_blocks_left(iter))
702 CALL dbcsr_iterator_next_block(iter, row, col, vec_bl, row_size=row_size, col_size=col_size)
703 prow = hash_table_get(fast_vec_col%hash_table, row)
704 fast_vec_col%blk_map_d (prow)%ptr(1:row_size, 1:col_size) = vec_bl(1:row_size, 1:col_size)
706 CALL dbcsr_iterator_stop(iter)
708 data_vec => dbcsr_get_data_p(work_col, select_data_type=0.0_real_8)
709 CALL prow_group%bcast(data_vec, 0)
712 CALL timeset(routinen//
"local_mm", handle1)
713 CALL dbcsr_get_info(matrix=work_col, nfullcols_local=ncols)
717 CALL dbcsr_iterator_start(iter, matrix, shared=.false.)
718 DO WHILE (dbcsr_iterator_blocks_left(iter))
719 CALL dbcsr_iterator_next_block(iter, row, col, data_d, row_size=row_size, col_size=col_size)
720 IF (skip_diag .AND. col == row) cycle
721 prow = hash_table_get(fast_vec_col%hash_table, row)
722 pcol = hash_table_get(fast_vec_row%hash_table, col)
723 IF (
ASSOCIATED(fast_vec_row%blk_map_d (pcol)%ptr) .AND. &
724 ASSOCIATED(fast_vec_col%blk_map_d (prow)%ptr))
THEN
725 IF (fast_vec_row%blk_map_d (pcol)%assigned_thread .NE. ithread) cycle
726 fast_vec_row%blk_map_d (pcol)%ptr = fast_vec_row%blk_map_d (pcol)%ptr + &
727 matmul(transpose(fast_vec_col%blk_map_d (prow)%ptr), data_d)
729 prow = hash_table_get(fast_vec_row%hash_table, row)
730 pcol = hash_table_get(fast_vec_col%hash_table, col)
731 IF (fast_vec_row%blk_map_d (prow)%assigned_thread .NE. ithread) cycle
732 fast_vec_row%blk_map_d (prow)%ptr = fast_vec_row%blk_map_d (prow)%ptr + &
733 matmul(transpose(fast_vec_col%blk_map_d (pcol)%ptr), transpose(data_d))
736 CALL dbcsr_iterator_stop(iter)
739 CALL timestop(handle1)
742 data_vec => dbcsr_get_data_p(work_row, select_data_type=0.0_real_8)
744 CALL dbcsr_get_info(matrix=work_row, nfullrows_local=nrows, nfullcols_local=ncols)
745 CALL pcol_group%sum(data_vec(1:nrows*ncols))
748 CALL dbcsr_rep_row_to_rep_col_vec_d (work_col, work_row, fast_vec_row)
751 CALL dbcsr_iterator_start(iter, vec_out)
752 DO WHILE (dbcsr_iterator_blocks_left(iter))
753 CALL dbcsr_iterator_next_block(iter, row, col, vec_res, row_size=row_size)
754 prow = hash_table_get(fast_vec_col%hash_table, row)
755 IF (
ASSOCIATED(fast_vec_col%blk_map_d (prow)%ptr))
THEN
756 vec_res(:, :) = beta*vec_res(:, :) + alpha*fast_vec_col%blk_map_d (prow)%ptr(:, :)
758 vec_res(:, :) = beta*vec_res(:, :)
761 CALL dbcsr_iterator_stop(iter)
763 CALL timestop(handle)
765 END SUBROUTINE dbcsr_matrixt_vector_mult_d
774 SUBROUTINE dbcsr_col_vec_to_rep_row_d (vec_in, rep_col_vec, rep_row_vec, fast_vec_col)
775 TYPE(dbcsr_type) :: vec_in, rep_col_vec, &
777 TYPE(fast_vec_access_type),
INTENT(IN) :: fast_vec_col
779 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_col_vec_to_rep_row'
781 INTEGER :: col, mypcol, myprow, ncols, &
782 nrows, pcol_handle, prow_handle, &
784 TYPE(mp_comm_type) :: pcol_group, prow_group
785 INTEGER,
DIMENSION(:),
POINTER :: local_cols, row_dist
786 REAL(kind=
real_8),
DIMENSION(:),
POINTER :: data_vec, data_vec_rep
787 REAL(kind=
real_8),
DIMENSION(:, :),
POINTER :: vec_row
788 TYPE(dbcsr_distribution_type) :: dist_in, dist_rep_col
789 TYPE(dbcsr_iterator_type) :: iter
791 CALL timeset(routinen, handle)
794 CALL dbcsr_get_info(vec_in, distribution=dist_in)
795 CALL dbcsr_distribution_get(dist_in, &
796 prow_group=prow_handle, &
797 pcol_group=pcol_handle, &
801 CALL prow_group%set_handle(prow_handle)
802 CALL pcol_group%set_handle(pcol_handle)
805 CALL dbcsr_get_info(rep_col_vec, distribution=dist_rep_col)
806 CALL dbcsr_distribution_get(dist_rep_col, row_dist=row_dist)
809 CALL dbcsr_get_info(matrix=rep_col_vec, nfullrows_local=nrows, nfullcols_local=ncols)
810 data_vec_rep => dbcsr_get_data_p(rep_col_vec, select_data_type=0.0_real_8)
811 data_vec => dbcsr_get_data_p(vec_in, select_data_type=0.0_real_8)
812 IF (mypcol == 0) data_vec_rep(1:nrows*ncols) = data_vec(1:nrows*ncols)
814 CALL prow_group%bcast(data_vec_rep(1:nrows*ncols), 0)
823 CALL dbcsr_set(rep_row_vec, 0.0_real_8)
824 CALL dbcsr_get_info(matrix=rep_row_vec, nfullrows_local=nrows, local_cols=local_cols, nfullcols_local=ncols)
825 CALL dbcsr_iterator_start(iter, rep_row_vec)
826 DO WHILE (dbcsr_iterator_blocks_left(iter))
827 CALL dbcsr_iterator_next_block(iter, row, col, vec_row)
828 IF (row_dist(col) == myprow)
THEN
829 vec_row = transpose(fast_vec_col%blk_map_d (hash_table_get(fast_vec_col%hash_table, col))%ptr)
832 CALL dbcsr_iterator_stop(iter)
833 CALL dbcsr_get_info(matrix=rep_row_vec, nfullrows_local=nrows, nfullcols_local=ncols)
834 data_vec_rep => dbcsr_get_data_p(rep_row_vec, select_data_type=0.0_real_8)
835 CALL pcol_group%sum(data_vec_rep(1:ncols*nrows))
837 CALL timestop(handle)
839 END SUBROUTINE dbcsr_col_vec_to_rep_row_d
848 SUBROUTINE dbcsr_rep_row_to_rep_col_vec_d (rep_col_vec, rep_row_vec, fast_vec_row, fast_vec_col_add)
849 TYPE(dbcsr_type) :: rep_col_vec, rep_row_vec
850 TYPE(fast_vec_access_type),
OPTIONAL :: fast_vec_col_add
851 TYPE(fast_vec_access_type) :: fast_vec_row
853 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_rep_row_to_rep_col_vec'
855 INTEGER :: col, mypcol, myprow, ncols, &
856 nrows, prow_handle, &
858 INTEGER,
DIMENSION(:),
POINTER :: col_dist
859 TYPE(mp_comm_type) :: prow_group
860 REAL(kind=
real_8),
DIMENSION(:),
POINTER :: data_vec_rep
861 REAL(kind=
real_8),
DIMENSION(:, :),
POINTER :: vec_col
862 TYPE(dbcsr_distribution_type) :: dist_rep_row, dist_rep_col
863 TYPE(dbcsr_iterator_type) :: iter
865 CALL timeset(routinen, handle)
868 CALL dbcsr_get_info(matrix=rep_col_vec, distribution=dist_rep_col)
869 CALL dbcsr_distribution_get(dist_rep_col, &
870 prow_group=prow_handle, &
874 CALL prow_group%set_handle(prow_handle)
877 CALL dbcsr_get_info(matrix=rep_row_vec, distribution=dist_rep_row)
878 CALL dbcsr_distribution_get(dist_rep_row, col_dist=col_dist)
881 CALL dbcsr_set(rep_col_vec, 0.0_real_8)
882 CALL dbcsr_iterator_start(iter, rep_col_vec)
883 DO WHILE (dbcsr_iterator_blocks_left(iter))
884 CALL dbcsr_iterator_next_block(iter, row, col, vec_col)
885 IF (col_dist(row) == mypcol)
THEN
886 vec_col = transpose(fast_vec_row%blk_map_d (hash_table_get(fast_vec_row%hash_table, row))%ptr)
890 IF (
PRESENT(fast_vec_col_add)) vec_col = vec_col + &
891 fast_vec_col_add%blk_map_d (hash_table_get(fast_vec_col_add%hash_table, row))%ptr(:, :)
893 CALL dbcsr_iterator_stop(iter)
894 CALL dbcsr_get_info(matrix=rep_col_vec, nfullrows_local=nrows, nfullcols_local=ncols)
895 data_vec_rep => dbcsr_get_data_p(rep_col_vec, select_data_type=0.0_real_8)
896 CALL prow_group%sum(data_vec_rep(1:nrows*ncols))
898 CALL timestop(handle)
900 END SUBROUTINE dbcsr_rep_row_to_rep_col_vec_d
907 SUBROUTINE create_fast_col_vec_access_d (vec, fast_vec_access)
908 TYPE(dbcsr_type) :: vec
909 TYPE(fast_vec_access_type) :: fast_vec_access
911 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_fast_col_vec_access_d'
913 INTEGER :: handle, nblk_local
914 INTEGER :: col, row, iblock, nthreads
915 REAL(kind=
real_8),
DIMENSION(:, :),
POINTER :: vec_bl
916 TYPE(dbcsr_iterator_type) :: iter
918 CALL timeset(routinen, handle)
928 CALL dbcsr_get_info(matrix=vec, nblkrows_local=nblk_local)
930 CALL hash_table_create(fast_vec_access%hash_table, 4*nblk_local)
932 ALLOCATE (fast_vec_access%blk_map_d (0:nblk_local))
934 CALL dbcsr_get_info(matrix=vec, nblkcols_local=col)
935 IF (col .GT. 1) cpabort(
"BUG")
939 CALL dbcsr_iterator_start(iter, vec)
940 DO WHILE (dbcsr_iterator_blocks_left(iter))
941 CALL dbcsr_iterator_next_block(iter, row, col, vec_bl)
943 CALL hash_table_add(fast_vec_access%hash_table, row, iblock)
944 fast_vec_access%blk_map_d (iblock)%ptr => vec_bl
945 fast_vec_access%blk_map_d (iblock)%assigned_thread = mod(iblock, nthreads)
947 CALL dbcsr_iterator_stop(iter)
949 CALL timestop(handle)
951 END SUBROUTINE create_fast_col_vec_access_d
958 SUBROUTINE create_fast_row_vec_access_d (vec, fast_vec_access)
959 TYPE(dbcsr_type) :: vec
960 TYPE(fast_vec_access_type) :: fast_vec_access
962 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_fast_row_vec_access_d'
964 INTEGER :: handle, nblk_local
965 INTEGER :: col, row, iblock, nthreads
966 REAL(kind=
real_8),
DIMENSION(:, :),
POINTER :: vec_bl
967 TYPE(dbcsr_iterator_type) :: iter
969 CALL timeset(routinen, handle)
979 CALL dbcsr_get_info(matrix=vec, nblkcols_local=nblk_local)
981 CALL hash_table_create(fast_vec_access%hash_table, 4*nblk_local)
983 ALLOCATE (fast_vec_access%blk_map_d (0:nblk_local))
986 CALL dbcsr_get_info(matrix=vec, nblkrows_local=row)
987 IF (row .GT. 1) cpabort(
"BUG")
991 CALL dbcsr_iterator_start(iter, vec)
992 DO WHILE (dbcsr_iterator_blocks_left(iter))
993 CALL dbcsr_iterator_next_block(iter, row, col, vec_bl)
995 CALL hash_table_add(fast_vec_access%hash_table, col, iblock)
996 fast_vec_access%blk_map_d (iblock)%ptr => vec_bl
997 fast_vec_access%blk_map_d (iblock)%assigned_thread = mod(iblock, nthreads)
999 CALL dbcsr_iterator_stop(iter)
1001 CALL timestop(handle)
1003 END SUBROUTINE create_fast_row_vec_access_d
1015 SUBROUTINE dbcsr_sym_matrix_vector_mult_d (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
1016 TYPE(dbcsr_type) :: matrix, vec_in, vec_out
1017 REAL(kind=
real_8) :: alpha, beta
1018 TYPE(dbcsr_type) :: work_row, work_col
1020 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_sym_m_v_mult'
1022 INTEGER :: col, mypcol, &
1026 handle, handle1, ithread, vec_dim
1027 REAL(kind=
real_8),
DIMENSION(:),
POINTER :: data_vec
1028 REAL(kind=
real_8),
DIMENSION(:, :),
POINTER :: data_d, vec_res
1029 TYPE(dbcsr_distribution_type) :: dist
1030 TYPE(dbcsr_iterator_type) :: iter
1031 TYPE(dbcsr_type) :: result_row, result_col
1032 TYPE(mp_comm_type) :: pcol_group
1034 TYPE(fast_vec_access_type) :: fast_vec_row, fast_vec_col, res_fast_vec_row, res_fast_vec_col
1035 INTEGER :: prow, pcol, rprow, rpcol
1037 CALL timeset(routinen, handle)
1040 CALL dbcsr_get_info(matrix=vec_in, nfullcols_total=vec_dim)
1042 CALL dbcsr_set(work_col, 0.0_real_8)
1043 CALL dbcsr_copy(result_col, work_col)
1044 CALL dbcsr_set(work_row, 0.0_real_8)
1045 CALL dbcsr_copy(result_row, work_row)
1048 CALL dbcsr_get_info(matrix=matrix, distribution=dist)
1049 CALL dbcsr_distribution_get(dist, pcol_group=pcol_handle, myprow=myprow, mypcol=mypcol)
1051 CALL pcol_group%set_handle(pcol_handle)
1053 CALL create_fast_row_vec_access(work_row, fast_vec_row)
1054 CALL create_fast_col_vec_access(work_col, fast_vec_col)
1055 CALL create_fast_row_vec_access(result_row, res_fast_vec_row)
1056 CALL create_fast_col_vec_access(result_col, res_fast_vec_col)
1059 CALL dbcsr_col_vec_to_rep_row_d (vec_in, work_col, work_row, fast_vec_col)
1065 CALL timeset(routinen//
"_local_mm", handle1)
1072 CALL dbcsr_iterator_start(iter, matrix, shared=.false.)
1073 DO WHILE (dbcsr_iterator_blocks_left(iter))
1074 CALL dbcsr_iterator_next_block(iter, row, col, data_d)
1075 pcol = hash_table_get(fast_vec_row%hash_table, col)
1076 rprow = hash_table_get(res_fast_vec_col%hash_table, row)
1077 IF (
ASSOCIATED(fast_vec_row%blk_map_d (pcol)%ptr) .AND. &
1078 ASSOCIATED(res_fast_vec_col%blk_map_d (rprow)%ptr))
THEN
1079 IF (res_fast_vec_col%blk_map_d (rprow)%assigned_thread .EQ. ithread)
THEN
1080 res_fast_vec_col%blk_map_d (rprow)%ptr = res_fast_vec_col%blk_map_d (rprow)%ptr + &
1081 matmul(data_d, transpose(fast_vec_row%blk_map_d (pcol)%ptr))
1083 prow = hash_table_get(fast_vec_col%hash_table, row)
1084 rpcol = hash_table_get(res_fast_vec_row%hash_table, col)
1085 IF (res_fast_vec_row%blk_map_d (rpcol)%assigned_thread .EQ. ithread .AND. row .NE. col)
THEN
1086 res_fast_vec_row%blk_map_d (rpcol)%ptr = res_fast_vec_row%blk_map_d (rpcol)%ptr + &
1087 matmul(transpose(fast_vec_col%blk_map_d (prow)%ptr), data_d)
1090 rpcol = hash_table_get(res_fast_vec_col%hash_table, col)
1091 prow = hash_table_get(fast_vec_row%hash_table, row)
1092 IF (res_fast_vec_col%blk_map_d (rpcol)%assigned_thread .EQ. ithread)
THEN
1093 res_fast_vec_col%blk_map_d (rpcol)%ptr = res_fast_vec_col%blk_map_d (rpcol)%ptr + &
1094 transpose(matmul(fast_vec_row%blk_map_d (prow)%ptr, data_d))
1096 rprow = hash_table_get(res_fast_vec_row%hash_table, row)
1097 pcol = hash_table_get(fast_vec_col%hash_table, col)
1098 IF (res_fast_vec_row%blk_map_d (rprow)%assigned_thread .EQ. ithread .AND. row .NE. col)
THEN
1099 res_fast_vec_row%blk_map_d (rprow)%ptr = res_fast_vec_row%blk_map_d (rprow)%ptr + &
1100 transpose(matmul(data_d, fast_vec_col%blk_map_d (pcol)%ptr))
1104 CALL dbcsr_iterator_stop(iter)
1107 CALL timestop(handle1)
1110 data_vec => dbcsr_get_data_p(result_row, select_data_type=0.0_real_8)
1111 CALL dbcsr_get_info(matrix=result_row, nfullrows_local=nrows, nfullcols_local=ncols)
1113 CALL pcol_group%sum(data_vec(1:nrows*ncols))
1119 CALL dbcsr_rep_row_to_rep_col_vec_d (work_col, result_row, res_fast_vec_row, res_fast_vec_col)
1122 CALL dbcsr_iterator_start(iter, vec_out)
1123 DO WHILE (dbcsr_iterator_blocks_left(iter))
1124 CALL dbcsr_iterator_next_block(iter, row, col, vec_res)
1125 prow = hash_table_get(fast_vec_col%hash_table, row)
1126 IF (
ASSOCIATED(fast_vec_col%blk_map_d (prow)%ptr))
THEN
1127 vec_res(:, :) = beta*vec_res(:, :) + alpha*(fast_vec_col%blk_map_d (prow)%ptr(:, :))
1129 vec_res(:, :) = beta*vec_res(:, :)
1132 CALL dbcsr_iterator_stop(iter)
1134 CALL release_fast_vec_access(fast_vec_row)
1135 CALL release_fast_vec_access(fast_vec_col)
1136 CALL release_fast_vec_access(res_fast_vec_row)
1137 CALL release_fast_vec_access(res_fast_vec_col)
1139 CALL dbcsr_release(result_row);
CALL dbcsr_release(result_col)
1141 CALL timestop(handle)
1143 END SUBROUTINE dbcsr_sym_matrix_vector_mult_d
1156 SUBROUTINE dbcsr_matrix_colvec_multiply_z (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
1157 TYPE(dbcsr_type) :: matrix, vec_in, vec_out
1158 COMPLEX(kind=real_8) :: alpha, beta
1159 TYPE(dbcsr_type) :: work_row, work_col
1161 CHARACTER :: matrix_type
1163 CALL dbcsr_get_info(matrix, matrix_type=matrix_type)
1165 SELECT CASE (matrix_type)
1166 CASE (dbcsr_type_no_symmetry)
1167 CALL dbcsr_matrix_vector_mult_z (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
1168 CASE (dbcsr_type_symmetric)
1169 CALL dbcsr_sym_matrix_vector_mult_z (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
1170 CASE (dbcsr_type_antisymmetric)
1172 cpabort(
"NYI, antisymmetric matrix not permitted")
1174 cpabort(
"Unknown matrix type, ...")
1177 END SUBROUTINE dbcsr_matrix_colvec_multiply_z
1189 SUBROUTINE dbcsr_matrix_vector_mult_z (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
1190 TYPE(dbcsr_type) :: matrix, vec_in, vec_out
1191 COMPLEX(kind=real_8) :: alpha, beta
1192 TYPE(dbcsr_type) :: work_row, work_col
1194 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_matrix_vector_mult'
1196 INTEGER :: col, mypcol, &
1197 myprow, prow_handle, &
1200 handle, handle1, ithread
1201 TYPE(mp_comm_type) :: prow_group
1202 COMPLEX(kind=real_8),
DIMENSION(:),
POINTER :: data_vec
1203 COMPLEX(kind=real_8),
DIMENSION(:, :),
POINTER :: data_d, vec_res
1204 TYPE(dbcsr_distribution_type) :: dist
1205 TYPE(dbcsr_iterator_type) :: iter
1206 TYPE(fast_vec_access_type) :: fast_vec_row, fast_vec_col
1207 INTEGER :: prow, pcol
1209 CALL timeset(routinen, handle)
1213 CALL dbcsr_get_info(matrix, distribution=dist)
1214 CALL dbcsr_distribution_get(dist, prow_group=prow_handle, myprow=myprow, mypcol=mypcol)
1216 CALL prow_group%set_handle(prow_handle)
1218 CALL create_fast_row_vec_access(work_row, fast_vec_row)
1219 CALL create_fast_col_vec_access(work_col, fast_vec_col)
1222 CALL dbcsr_col_vec_to_rep_row_z (vec_in, work_col, work_row, fast_vec_col)
1225 CALL dbcsr_set(work_col, cmplx(0.0, 0.0,
real_8))
1229 CALL timeset(routinen//
"_local_mm", handle1)
1234 CALL dbcsr_iterator_start(iter, matrix, shared=.false.)
1235 DO WHILE (dbcsr_iterator_blocks_left(iter))
1236 CALL dbcsr_iterator_next_block(iter, row, col, data_d)
1237 prow = hash_table_get(fast_vec_col%hash_table, row)
1238 IF (fast_vec_col%blk_map_z (prow)%assigned_thread .NE. ithread) cycle
1239 pcol = hash_table_get(fast_vec_row%hash_table, col)
1240 fast_vec_col%blk_map_z (prow)%ptr = fast_vec_col%blk_map_z (prow)%ptr + &
1241 matmul(data_d, transpose(fast_vec_row%blk_map_z (pcol)%ptr))
1243 CALL dbcsr_iterator_stop(iter)
1246 CALL timestop(handle1)
1249 data_vec => dbcsr_get_data_p(work_col, select_data_type=cmplx(0.0, 0.0,
real_8))
1250 CALL dbcsr_get_info(matrix=work_col, nfullrows_local=nrows, nfullcols_local=ncols)
1251 CALL prow_group%sum(data_vec(1:nrows*ncols))
1255 CALL dbcsr_iterator_start(iter, vec_out)
1256 DO WHILE (dbcsr_iterator_blocks_left(iter))
1257 CALL dbcsr_iterator_next_block(iter, row, col, vec_res)
1258 prow = hash_table_get(fast_vec_col%hash_table, row)
1259 IF (
ASSOCIATED(fast_vec_col%blk_map_z (prow)%ptr))
THEN
1260 vec_res(:, :) = beta*vec_res(:, :) + alpha*fast_vec_col%blk_map_z (prow)%ptr(:, :)
1262 vec_res(:, :) = beta*vec_res(:, :)
1265 CALL dbcsr_iterator_stop(iter)
1267 CALL release_fast_vec_access(fast_vec_row)
1268 CALL release_fast_vec_access(fast_vec_col)
1270 CALL timestop(handle)
1272 END SUBROUTINE dbcsr_matrix_vector_mult_z
1285 SUBROUTINE dbcsr_matrixt_vector_mult_z (matrix, vec_in, vec_out, alpha, beta, work_row, work_col, skip_diag)
1286 TYPE(dbcsr_type) :: matrix, vec_in, vec_out
1287 COMPLEX(kind=real_8) :: alpha, beta
1288 TYPE(dbcsr_type) :: work_row, work_col
1289 LOGICAL :: skip_diag
1291 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_matrixT_vector_mult'
1293 INTEGER :: col, col_size, mypcol, &
1294 myprow, pcol_handle, prow_handle, &
1297 handle, handle1, ithread
1298 TYPE(mp_comm_type) :: pcol_group, prow_group
1299 COMPLEX(kind=real_8),
DIMENSION(:),
POINTER :: data_vec
1300 COMPLEX(kind=real_8),
DIMENSION(:, :),
POINTER :: data_d, vec_bl, vec_res
1301 TYPE(dbcsr_distribution_type) :: dist
1302 TYPE(dbcsr_iterator_type) :: iter
1304 TYPE(fast_vec_access_type) :: fast_vec_row, fast_vec_col
1305 INTEGER :: prow, pcol
1307 CALL timeset(routinen, handle)
1311 CALL dbcsr_get_info(matrix, distribution=dist)
1312 CALL dbcsr_distribution_get(dist, prow_group=prow_handle, pcol_group=pcol_handle, myprow=myprow, mypcol=mypcol)
1314 CALL prow_group%set_handle(prow_handle)
1315 CALL pcol_group%set_handle(pcol_handle)
1317 CALL create_fast_row_vec_access(work_row, fast_vec_row)
1318 CALL create_fast_col_vec_access(work_col, fast_vec_col)
1321 CALL dbcsr_set(work_row, cmplx(0.0, 0.0,
real_8))
1324 CALL dbcsr_iterator_start(iter, vec_in)
1325 DO WHILE (dbcsr_iterator_blocks_left(iter))
1326 CALL dbcsr_iterator_next_block(iter, row, col, vec_bl, row_size=row_size, col_size=col_size)
1327 prow = hash_table_get(fast_vec_col%hash_table, row)
1328 fast_vec_col%blk_map_z (prow)%ptr(1:row_size, 1:col_size) = vec_bl(1:row_size, 1:col_size)
1330 CALL dbcsr_iterator_stop(iter)
1332 data_vec => dbcsr_get_data_p(work_col, select_data_type=cmplx(0.0, 0.0,
real_8))
1333 CALL prow_group%bcast(data_vec, 0)
1336 CALL timeset(routinen//
"local_mm", handle1)
1337 CALL dbcsr_get_info(matrix=work_col, nfullcols_local=ncols)
1341 CALL dbcsr_iterator_start(iter, matrix, shared=.false.)
1342 DO WHILE (dbcsr_iterator_blocks_left(iter))
1343 CALL dbcsr_iterator_next_block(iter, row, col, data_d, row_size=row_size, col_size=col_size)
1344 IF (skip_diag .AND. col == row) cycle
1345 prow = hash_table_get(fast_vec_col%hash_table, row)
1346 pcol = hash_table_get(fast_vec_row%hash_table, col)
1347 IF (
ASSOCIATED(fast_vec_row%blk_map_z (pcol)%ptr) .AND. &
1348 ASSOCIATED(fast_vec_col%blk_map_z (prow)%ptr))
THEN
1349 IF (fast_vec_row%blk_map_z (pcol)%assigned_thread .NE. ithread) cycle
1350 fast_vec_row%blk_map_z (pcol)%ptr = fast_vec_row%blk_map_z (pcol)%ptr + &
1351 matmul(transpose(fast_vec_col%blk_map_z (prow)%ptr), data_d)
1353 prow = hash_table_get(fast_vec_row%hash_table, row)
1354 pcol = hash_table_get(fast_vec_col%hash_table, col)
1355 IF (fast_vec_row%blk_map_z (prow)%assigned_thread .NE. ithread) cycle
1356 fast_vec_row%blk_map_z (prow)%ptr = fast_vec_row%blk_map_z (prow)%ptr + &
1357 matmul(transpose(fast_vec_col%blk_map_z (pcol)%ptr), transpose(data_d))
1360 CALL dbcsr_iterator_stop(iter)
1363 CALL timestop(handle1)
1366 data_vec => dbcsr_get_data_p(work_row, select_data_type=cmplx(0.0, 0.0,
real_8))
1368 CALL dbcsr_get_info(matrix=work_row, nfullrows_local=nrows, nfullcols_local=ncols)
1369 CALL pcol_group%sum(data_vec(1:nrows*ncols))
1372 CALL dbcsr_rep_row_to_rep_col_vec_z (work_col, work_row, fast_vec_row)
1375 CALL dbcsr_iterator_start(iter, vec_out)
1376 DO WHILE (dbcsr_iterator_blocks_left(iter))
1377 CALL dbcsr_iterator_next_block(iter, row, col, vec_res, row_size=row_size)
1378 prow = hash_table_get(fast_vec_col%hash_table, row)
1379 IF (
ASSOCIATED(fast_vec_col%blk_map_z (prow)%ptr))
THEN
1380 vec_res(:, :) = beta*vec_res(:, :) + alpha*fast_vec_col%blk_map_z (prow)%ptr(:, :)
1382 vec_res(:, :) = beta*vec_res(:, :)
1385 CALL dbcsr_iterator_stop(iter)
1387 CALL timestop(handle)
1389 END SUBROUTINE dbcsr_matrixt_vector_mult_z
1398 SUBROUTINE dbcsr_col_vec_to_rep_row_z (vec_in, rep_col_vec, rep_row_vec, fast_vec_col)
1399 TYPE(dbcsr_type) :: vec_in, rep_col_vec, &
1401 TYPE(fast_vec_access_type),
INTENT(IN) :: fast_vec_col
1403 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_col_vec_to_rep_row'
1405 INTEGER :: col, mypcol, myprow, ncols, &
1406 nrows, pcol_handle, prow_handle, &
1408 TYPE(mp_comm_type) :: pcol_group, prow_group
1409 INTEGER,
DIMENSION(:),
POINTER :: local_cols, row_dist
1410 COMPLEX(kind=real_8),
DIMENSION(:),
POINTER :: data_vec, data_vec_rep
1411 COMPLEX(kind=real_8),
DIMENSION(:, :),
POINTER :: vec_row
1412 TYPE(dbcsr_distribution_type) :: dist_in, dist_rep_col
1413 TYPE(dbcsr_iterator_type) :: iter
1415 CALL timeset(routinen, handle)
1418 CALL dbcsr_get_info(vec_in, distribution=dist_in)
1419 CALL dbcsr_distribution_get(dist_in, &
1420 prow_group=prow_handle, &
1421 pcol_group=pcol_handle, &
1425 CALL prow_group%set_handle(prow_handle)
1426 CALL pcol_group%set_handle(pcol_handle)
1429 CALL dbcsr_get_info(rep_col_vec, distribution=dist_rep_col)
1430 CALL dbcsr_distribution_get(dist_rep_col, row_dist=row_dist)
1433 CALL dbcsr_get_info(matrix=rep_col_vec, nfullrows_local=nrows, nfullcols_local=ncols)
1434 data_vec_rep => dbcsr_get_data_p(rep_col_vec, select_data_type=cmplx(0.0, 0.0,
real_8))
1435 data_vec => dbcsr_get_data_p(vec_in, select_data_type=cmplx(0.0, 0.0,
real_8))
1436 IF (mypcol == 0) data_vec_rep(1:nrows*ncols) = data_vec(1:nrows*ncols)
1438 CALL prow_group%bcast(data_vec_rep(1:nrows*ncols), 0)
1447 CALL dbcsr_set(rep_row_vec, cmplx(0.0, 0.0,
real_8))
1448 CALL dbcsr_get_info(matrix=rep_row_vec, nfullrows_local=nrows, local_cols=local_cols, nfullcols_local=ncols)
1449 CALL dbcsr_iterator_start(iter, rep_row_vec)
1450 DO WHILE (dbcsr_iterator_blocks_left(iter))
1451 CALL dbcsr_iterator_next_block(iter, row, col, vec_row)
1452 IF (row_dist(col) == myprow)
THEN
1453 vec_row = transpose(fast_vec_col%blk_map_z (hash_table_get(fast_vec_col%hash_table, col))%ptr)
1456 CALL dbcsr_iterator_stop(iter)
1457 CALL dbcsr_get_info(matrix=rep_row_vec, nfullrows_local=nrows, nfullcols_local=ncols)
1458 data_vec_rep => dbcsr_get_data_p(rep_row_vec, select_data_type=cmplx(0.0, 0.0,
real_8))
1459 CALL pcol_group%sum(data_vec_rep(1:ncols*nrows))
1461 CALL timestop(handle)
1463 END SUBROUTINE dbcsr_col_vec_to_rep_row_z
1472 SUBROUTINE dbcsr_rep_row_to_rep_col_vec_z (rep_col_vec, rep_row_vec, fast_vec_row, fast_vec_col_add)
1473 TYPE(dbcsr_type) :: rep_col_vec, rep_row_vec
1474 TYPE(fast_vec_access_type),
OPTIONAL :: fast_vec_col_add
1475 TYPE(fast_vec_access_type) :: fast_vec_row
1477 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_rep_row_to_rep_col_vec'
1479 INTEGER :: col, mypcol, myprow, ncols, &
1480 nrows, prow_handle, &
1482 INTEGER,
DIMENSION(:),
POINTER :: col_dist
1483 TYPE(mp_comm_type) :: prow_group
1484 COMPLEX(kind=real_8),
DIMENSION(:),
POINTER :: data_vec_rep
1485 COMPLEX(kind=real_8),
DIMENSION(:, :),
POINTER :: vec_col
1486 TYPE(dbcsr_distribution_type) :: dist_rep_row, dist_rep_col
1487 TYPE(dbcsr_iterator_type) :: iter
1489 CALL timeset(routinen, handle)
1492 CALL dbcsr_get_info(matrix=rep_col_vec, distribution=dist_rep_col)
1493 CALL dbcsr_distribution_get(dist_rep_col, &
1494 prow_group=prow_handle, &
1498 CALL prow_group%set_handle(prow_handle)
1501 CALL dbcsr_get_info(matrix=rep_row_vec, distribution=dist_rep_row)
1502 CALL dbcsr_distribution_get(dist_rep_row, col_dist=col_dist)
1505 CALL dbcsr_set(rep_col_vec, cmplx(0.0, 0.0,
real_8))
1506 CALL dbcsr_iterator_start(iter, rep_col_vec)
1507 DO WHILE (dbcsr_iterator_blocks_left(iter))
1508 CALL dbcsr_iterator_next_block(iter, row, col, vec_col)
1509 IF (col_dist(row) == mypcol)
THEN
1510 vec_col = transpose(fast_vec_row%blk_map_z (hash_table_get(fast_vec_row%hash_table, row))%ptr)
1514 IF (
PRESENT(fast_vec_col_add)) vec_col = vec_col + &
1515 fast_vec_col_add%blk_map_z (hash_table_get(fast_vec_col_add%hash_table, row))%ptr(:, :)
1517 CALL dbcsr_iterator_stop(iter)
1518 CALL dbcsr_get_info(matrix=rep_col_vec, nfullrows_local=nrows, nfullcols_local=ncols)
1519 data_vec_rep => dbcsr_get_data_p(rep_col_vec, select_data_type=cmplx(0.0, 0.0,
real_8))
1520 CALL prow_group%sum(data_vec_rep(1:nrows*ncols))
1522 CALL timestop(handle)
1524 END SUBROUTINE dbcsr_rep_row_to_rep_col_vec_z
1531 SUBROUTINE create_fast_col_vec_access_z (vec, fast_vec_access)
1532 TYPE(dbcsr_type) :: vec
1533 TYPE(fast_vec_access_type) :: fast_vec_access
1535 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_fast_col_vec_access_z'
1537 INTEGER :: handle, nblk_local
1538 INTEGER :: col, row, iblock, nthreads
1539 COMPLEX(kind=real_8),
DIMENSION(:, :),
POINTER :: vec_bl
1540 TYPE(dbcsr_iterator_type) :: iter
1542 CALL timeset(routinen, handle)
1552 CALL dbcsr_get_info(matrix=vec, nblkrows_local=nblk_local)
1554 CALL hash_table_create(fast_vec_access%hash_table, 4*nblk_local)
1556 ALLOCATE (fast_vec_access%blk_map_z (0:nblk_local))
1558 CALL dbcsr_get_info(matrix=vec, nblkcols_local=col)
1559 IF (col .GT. 1) cpabort(
"BUG")
1563 CALL dbcsr_iterator_start(iter, vec)
1564 DO WHILE (dbcsr_iterator_blocks_left(iter))
1565 CALL dbcsr_iterator_next_block(iter, row, col, vec_bl)
1567 CALL hash_table_add(fast_vec_access%hash_table, row, iblock)
1568 fast_vec_access%blk_map_z (iblock)%ptr => vec_bl
1569 fast_vec_access%blk_map_z (iblock)%assigned_thread = mod(iblock, nthreads)
1571 CALL dbcsr_iterator_stop(iter)
1573 CALL timestop(handle)
1575 END SUBROUTINE create_fast_col_vec_access_z
1582 SUBROUTINE create_fast_row_vec_access_z (vec, fast_vec_access)
1583 TYPE(dbcsr_type) :: vec
1584 TYPE(fast_vec_access_type) :: fast_vec_access
1586 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_fast_row_vec_access_z'
1588 INTEGER :: handle, nblk_local
1589 INTEGER :: col, row, iblock, nthreads
1590 COMPLEX(kind=real_8),
DIMENSION(:, :),
POINTER :: vec_bl
1591 TYPE(dbcsr_iterator_type) :: iter
1593 CALL timeset(routinen, handle)
1603 CALL dbcsr_get_info(matrix=vec, nblkcols_local=nblk_local)
1605 CALL hash_table_create(fast_vec_access%hash_table, 4*nblk_local)
1607 ALLOCATE (fast_vec_access%blk_map_z (0:nblk_local))
1610 CALL dbcsr_get_info(matrix=vec, nblkrows_local=row)
1611 IF (row .GT. 1) cpabort(
"BUG")
1615 CALL dbcsr_iterator_start(iter, vec)
1616 DO WHILE (dbcsr_iterator_blocks_left(iter))
1617 CALL dbcsr_iterator_next_block(iter, row, col, vec_bl)
1619 CALL hash_table_add(fast_vec_access%hash_table, col, iblock)
1620 fast_vec_access%blk_map_z (iblock)%ptr => vec_bl
1621 fast_vec_access%blk_map_z (iblock)%assigned_thread = mod(iblock, nthreads)
1623 CALL dbcsr_iterator_stop(iter)
1625 CALL timestop(handle)
1627 END SUBROUTINE create_fast_row_vec_access_z
1639 SUBROUTINE dbcsr_sym_matrix_vector_mult_z (matrix, vec_in, vec_out, alpha, beta, work_row, work_col)
1640 TYPE(dbcsr_type) :: matrix, vec_in, vec_out
1641 COMPLEX(kind=real_8) :: alpha, beta
1642 TYPE(dbcsr_type) :: work_row, work_col
1644 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbcsr_sym_m_v_mult'
1646 INTEGER :: col, mypcol, &
1650 handle, handle1, ithread, vec_dim
1651 COMPLEX(kind=real_8),
DIMENSION(:),
POINTER :: data_vec
1652 COMPLEX(kind=real_8),
DIMENSION(:, :),
POINTER :: data_d, vec_res
1653 TYPE(dbcsr_distribution_type) :: dist
1654 TYPE(dbcsr_iterator_type) :: iter
1655 TYPE(dbcsr_type) :: result_row, result_col
1656 TYPE(mp_comm_type) :: pcol_group
1658 TYPE(fast_vec_access_type) :: fast_vec_row, fast_vec_col, res_fast_vec_row, res_fast_vec_col
1659 INTEGER :: prow, pcol, rprow, rpcol
1661 CALL timeset(routinen, handle)
1664 CALL dbcsr_get_info(matrix=vec_in, nfullcols_total=vec_dim)
1666 CALL dbcsr_set(work_col, cmplx(0.0, 0.0,
real_8))
1667 CALL dbcsr_copy(result_col, work_col)
1668 CALL dbcsr_set(work_row, cmplx(0.0, 0.0,
real_8))
1669 CALL dbcsr_copy(result_row, work_row)
1672 CALL dbcsr_get_info(matrix=matrix, distribution=dist)
1673 CALL dbcsr_distribution_get(dist, pcol_group=pcol_handle, myprow=myprow, mypcol=mypcol)
1675 CALL pcol_group%set_handle(pcol_handle)
1677 CALL create_fast_row_vec_access(work_row, fast_vec_row)
1678 CALL create_fast_col_vec_access(work_col, fast_vec_col)
1679 CALL create_fast_row_vec_access(result_row, res_fast_vec_row)
1680 CALL create_fast_col_vec_access(result_col, res_fast_vec_col)
1683 CALL dbcsr_col_vec_to_rep_row_z (vec_in, work_col, work_row, fast_vec_col)
1689 CALL timeset(routinen//
"_local_mm", handle1)
1696 CALL dbcsr_iterator_start(iter, matrix, shared=.false.)
1697 DO WHILE (dbcsr_iterator_blocks_left(iter))
1698 CALL dbcsr_iterator_next_block(iter, row, col, data_d)
1699 pcol = hash_table_get(fast_vec_row%hash_table, col)
1700 rprow = hash_table_get(res_fast_vec_col%hash_table, row)
1701 IF (
ASSOCIATED(fast_vec_row%blk_map_z (pcol)%ptr) .AND. &
1702 ASSOCIATED(res_fast_vec_col%blk_map_z (rprow)%ptr))
THEN
1703 IF (res_fast_vec_col%blk_map_z (rprow)%assigned_thread .EQ. ithread)
THEN
1704 res_fast_vec_col%blk_map_z (rprow)%ptr = res_fast_vec_col%blk_map_z (rprow)%ptr + &
1705 matmul(data_d, transpose(fast_vec_row%blk_map_z (pcol)%ptr))
1707 prow = hash_table_get(fast_vec_col%hash_table, row)
1708 rpcol = hash_table_get(res_fast_vec_row%hash_table, col)
1709 IF (res_fast_vec_row%blk_map_z (rpcol)%assigned_thread .EQ. ithread .AND. row .NE. col)
THEN
1710 res_fast_vec_row%blk_map_z (rpcol)%ptr = res_fast_vec_row%blk_map_z (rpcol)%ptr + &
1711 matmul(transpose(fast_vec_col%blk_map_z (prow)%ptr), data_d)
1714 rpcol = hash_table_get(res_fast_vec_col%hash_table, col)
1715 prow = hash_table_get(fast_vec_row%hash_table, row)
1716 IF (res_fast_vec_col%blk_map_z (rpcol)%assigned_thread .EQ. ithread)
THEN
1717 res_fast_vec_col%blk_map_z (rpcol)%ptr = res_fast_vec_col%blk_map_z (rpcol)%ptr + &
1718 transpose(matmul(fast_vec_row%blk_map_z (prow)%ptr, data_d))
1720 rprow = hash_table_get(res_fast_vec_row%hash_table, row)
1721 pcol = hash_table_get(fast_vec_col%hash_table, col)
1722 IF (res_fast_vec_row%blk_map_z (rprow)%assigned_thread .EQ. ithread .AND. row .NE. col)
THEN
1723 res_fast_vec_row%blk_map_z (rprow)%ptr = res_fast_vec_row%blk_map_z (rprow)%ptr + &
1724 transpose(matmul(data_d, fast_vec_col%blk_map_z (pcol)%ptr))
1728 CALL dbcsr_iterator_stop(iter)
1731 CALL timestop(handle1)
1734 data_vec => dbcsr_get_data_p(result_row, select_data_type=cmplx(0.0, 0.0,
real_8))
1735 CALL dbcsr_get_info(matrix=result_row, nfullrows_local=nrows, nfullcols_local=ncols)
1737 CALL pcol_group%sum(data_vec(1:nrows*ncols))
1743 CALL dbcsr_rep_row_to_rep_col_vec_z (work_col, result_row, res_fast_vec_row, res_fast_vec_col)
1746 CALL dbcsr_iterator_start(iter, vec_out)
1747 DO WHILE (dbcsr_iterator_blocks_left(iter))
1748 CALL dbcsr_iterator_next_block(iter, row, col, vec_res)
1749 prow = hash_table_get(fast_vec_col%hash_table, row)
1750 IF (
ASSOCIATED(fast_vec_col%blk_map_z (prow)%ptr))
THEN
1751 vec_res(:, :) = beta*vec_res(:, :) + alpha*(fast_vec_col%blk_map_z (prow)%ptr(:, :))
1753 vec_res(:, :) = beta*vec_res(:, :)
1756 CALL dbcsr_iterator_stop(iter)
1758 CALL release_fast_vec_access(fast_vec_row)
1759 CALL release_fast_vec_access(fast_vec_col)
1760 CALL release_fast_vec_access(res_fast_vec_row)
1761 CALL release_fast_vec_access(res_fast_vec_col)
1763 CALL dbcsr_release(result_row);
CALL dbcsr_release(result_col)
1765 CALL timestop(handle)
1767 END SUBROUTINE dbcsr_sym_matrix_vector_mult_z
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.
operations for skinny matrices/vectors expressed in dbcsr form
subroutine, public create_replicated_row_vec_from_matrix(dbcsr_vec, matrix, nrow)
creates a row vector like object whose blocks can be replicated along the processor col and has the s...
subroutine, public create_col_vec_from_matrix(dbcsr_vec, matrix, ncol)
creates a dbcsr col vector like object which lives on proc_col 0 and has the same row dist as the tem...
subroutine, public create_replicated_col_vec_from_matrix(dbcsr_vec, matrix, ncol)
creates a col vector like object whose blocks can be replicated along the processor row and has the s...
subroutine, public create_row_vec_from_matrix(dbcsr_vec, matrix, nrow)
creates a dbcsr row vector like object which lives on proc_row 0 and has the same row dist as the tem...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public real_8
Interface to the message passing library MPI.