64#include "./base/base_uses.f90"
69 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'preconditioner_apply'
75 TYPE complex_preconditioner_work_type
76 COMPLEX(dp),
ALLOCATABLE :: buffer(:, :, :)
77 REAL(dp),
ALLOCATABLE :: packed(:, :, :)
78 TYPE(local_gemm_ctxt_type) :: gemm_ctx
79 END TYPE complex_preconditioner_work_type
94 TYPE(
dbcsr_p_type),
INTENT(IN) :: matrix_in(:, :), matrix_out(:, :)
95 LOGICAL,
INTENT(OUT) :: handled
96 REAL(
dp),
INTENT(IN),
OPTIONAL :: output_scale(:)
98 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_preconditioner_complex_batch'
100 INTEGER :: first, handle, i, j, k, n, nbatch, &
102 TYPE(complex_preconditioner_work_type), &
103 ALLOCATABLE :: work(:)
107 nchannels =
SIZE(preconditioners)
108 IF (nchannels == 0)
RETURN
110 p => preconditioners(i)%preconditioner
111 IF (.NOT.
ASSOCIATED(p))
RETURN
112 IF (.NOT.
ASSOCIATED(p%complex_fm))
RETURN
113 IF (p%complex_fm%matrix_struct%para_env%num_pe /= 1)
RETURN
114 SELECT CASE (p%in_use)
123 CALL timeset(routinen, handle)
126 ALLOCATE (work(nworkers))
130 DO first = 1, nchannels, nworkers
131 nbatch = min(nworkers, nchannels - first + 1)
134 p => preconditioners(i)%preconditioner
135 CALL dbcsr_get_info(matrix_in(1, i)%matrix, nfullrows_total=n, nfullcols_total=k)
136 cpassert(n == p%complex_fm%matrix_struct%nrow_global)
137 IF (
ALLOCATED(work(j)%buffer))
THEN
138 IF (
SIZE(work(j)%buffer, 1) /= n .OR.
SIZE(work(j)%buffer, 2) /= k)
THEN
139 DEALLOCATE (work(j)%buffer, work(j)%packed)
142 IF (.NOT.
ALLOCATED(work(j)%buffer))
THEN
143 ALLOCATE (work(j)%buffer(n, k, 2), work(j)%packed(n, k, 2))
152 CALL apply_preconditioner_complex_local(preconditioners(i)%preconditioner, work(j))
153 IF (
PRESENT(output_scale))
THEN
154 IF (output_scale(i) /= 1.0_dp) work(j)%packed(:, :, :) = output_scale(i)*work(j)%packed(:, :, :)
165 CALL work(j)%gemm_ctx%destroy()
168 CALL timestop(handle)
176 SUBROUTINE apply_preconditioner_complex_local(p, w)
178 TYPE(complex_preconditioner_work_type), &
179 INTENT(INOUT),
TARGET :: w
181 COMPLEX(dp),
CONTIGUOUS,
POINTER :: basis(:, :), result(:, :), rhs(:, :), &
186 n =
SIZE(w%buffer, 1)
187 k =
SIZE(w%buffer, 2)
188 IF (n == 0 .OR. k == 0)
RETURN
189 basis => p%complex_fm%local_data
190 rhs => w%buffer(:, :, 1)
191 result => w%buffer(:, :, 2)
192 rhs(:, :) = cmplx(w%packed(:, :, 1), w%packed(:, :, 2), kind=
dp)
193 SELECT CASE (p%in_use)
195 cpassert(
ASSOCIATED(p%full_evals))
196 cpassert(
ASSOCIATED(p%occ_evals))
197 cpassert(n ==
SIZE(p%full_evals))
199 cpassert(k ==
SIZE(p%occ_evals))
202 cpassert(
ASSOCIATED(p%occ_rotation_complex))
203 rotation => p%occ_rotation_complex%local_data
204 CALL w%gemm_ctx%gemm(
'N',
'N', n, k, k,
z_one, rhs, n, &
205 rotation,
SIZE(rotation, 1),
z_zero, result, n)
206 rhs => w%buffer(:, :, 2)
207 result => w%buffer(:, :, 1)
209 CALL w%gemm_ctx%gemm(
'C',
'N', n, k, n,
z_one, basis,
SIZE(basis, 1), &
210 rhs, n,
z_zero, result, n)
211 CALL scale_complex_spectral(p, result, p%complex_fm%matrix_struct%row_indices, &
212 p%complex_fm%matrix_struct%col_indices)
213 CALL w%gemm_ctx%gemm(
'N',
'N', n, k, n,
z_one, basis,
SIZE(basis, 1), &
214 result, n,
z_zero, rhs, n)
216 CALL w%gemm_ctx%gemm(
'N',
'C', n, k, k,
z_one, rhs, n, &
217 rotation,
SIZE(rotation, 1),
z_zero, result, n)
222 CALL w%gemm_ctx%gemm(
'N',
'N', n, k, n,
z_one, basis,
SIZE(basis, 1), &
223 rhs, n,
z_zero, result, n)
225 w%packed(:, :, 1) = real(result, kind=
dp)
226 w%packed(:, :, 2) = aimag(result)
227 END SUBROUTINE apply_preconditioner_complex_local
236 SUBROUTINE scale_complex_spectral(p, DATA, rows, cols)
238 COMPLEX(dp),
INTENT(INOUT) :: data(:, :)
239 INTEGER,
INTENT(IN) :: rows(:), cols(:)
241 INTEGER :: i, j, nocc, rank_used
245 nocc =
SIZE(p%occ_evals)
246 rank_used = min(p%spectral_rank,
SIZE(p%full_evals) - nocc)
247 DO i = 1,
SIZE(
DATA, 1)
248 scale = p%spectral_base_scale
249 IF (rows(i) > nocc .AND. rows(i) <= nocc + rank_used)
THEN
252 DATA(i, :) = scale*
DATA(i, :)
255 DO j = 1,
SIZE(
DATA, 2)
256 DO i = 1,
SIZE(
DATA, 1)
257 scale = 1.0_dp/max(p%energy_gap, p%full_evals(rows(i)) - p%occ_evals(cols(j)))
258 DATA(i, j) = scale*
DATA(i, j)
262 END SUBROUTINE scale_complex_spectral
273 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
275 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_preconditioner_fm'
279 CALL timeset(routinen, handle)
281 SELECT CASE (preconditioner_env%in_use)
283 cpabort(
"No preconditioner in use")
285 CALL apply_full_single(preconditioner_env, matrix_in, matrix_out)
287 CALL apply_full_all(preconditioner_env, matrix_in, matrix_out)
289 CALL apply_low_rank_fm(preconditioner_env, matrix_in, matrix_out)
291 CALL apply_full_all_covariant(preconditioner_env, matrix_in, matrix_out)
293 IF (preconditioner_env%lattice_fft_active)
THEN
294 CALL apply_lattice_operator_fm(preconditioner_env, matrix_in, matrix_out)
296 SELECT CASE (preconditioner_env%solver)
298 CALL apply_full_single(preconditioner_env, matrix_in, matrix_out)
300 CALL apply_full_direct(preconditioner_env, matrix_in, matrix_out)
302 CALL apply_chebyshev_fm(preconditioner_env, matrix_in, matrix_out)
304 cpabort(
"Solver not implemented")
308 cpabort(
"Unknown preconditioner")
311 CALL timestop(handle)
326 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_preconditioner_dbcsr'
330 CALL timeset(routinen, handle)
332 SELECT CASE (preconditioner_env%in_use)
334 cpabort(
"No preconditioner in use")
336 CALL apply_single(preconditioner_env, matrix_in, matrix_out)
338 CALL apply_all(preconditioner_env, matrix_in, matrix_out)
340 CALL apply_low_rank_dbcsr(preconditioner_env, matrix_in, matrix_out)
342 CALL apply_all_covariant(preconditioner_env, matrix_in, matrix_out)
344 IF (preconditioner_env%lattice_fft_active)
THEN
345 CALL apply_lattice_operator_dbcsr(preconditioner_env, matrix_in, matrix_out)
347 SELECT CASE (preconditioner_env%solver)
349 CALL apply_single(preconditioner_env, matrix_in, matrix_out)
351 cpabort(
"Apply_full_direct not supported with ot")
354 CALL apply_chebyshev_dbcsr(preconditioner_env, matrix_in, matrix_out)
356 cpabort(
"Wrong solver")
360 cpabort(
"Wrong preconditioner")
363 CALL timestop(handle)
379 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_preconditioner_cfm_complex'
381 INTEGER :: handle, k, n, npre
384 CALL timeset(routinen, handle)
386 SELECT CASE (preconditioner_env%in_use)
391 cpabort(
"Unsupported complex K-point OT preconditioner")
393 cpassert(
ASSOCIATED(preconditioner_env%complex_fm))
398 SELECT CASE (preconditioner_env%in_use)
400 CALL apply_complex_spectral(preconditioner_env, matrix_in, matrix_out)
402 cpassert(
ASSOCIATED(preconditioner_env%occ_rotation_complex))
404 name=
'complex covariant FULL_ALL input')
405 CALL cp_cfm_create(canonical_out, matrix_out%matrix_struct, &
406 name=
'complex covariant FULL_ALL output')
408 preconditioner_env%occ_rotation_complex,
z_zero, canonical_in)
409 CALL apply_complex_spectral(preconditioner_env, canonical_in, canonical_out)
411 preconditioner_env%occ_rotation_complex,
z_zero, matrix_out)
416 matrix_in,
z_zero, matrix_out)
419 CALL timestop(handle)
429 SUBROUTINE apply_complex_spectral(preconditioner_env, matrix_in, matrix_out)
435 COMPLEX(KIND=dp),
CONTIGUOUS,
DIMENSION(:, :), &
436 POINTER :: local_data
437 INTEGER :: k, n, ncol_local, nrow_local
438 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
441 cpassert(
ASSOCIATED(preconditioner_env%full_evals))
442 cpassert(
ASSOCIATED(preconditioner_env%occ_evals))
444 cpassert(n ==
SIZE(preconditioner_env%full_evals))
446 cpassert(k ==
SIZE(preconditioner_env%occ_evals))
448 CALL cp_cfm_create(matrix_spectral, matrix_in%matrix_struct, &
449 name=
'complex spectral input')
451 matrix_in,
z_zero, matrix_spectral)
452 CALL cp_cfm_get_info(matrix_spectral, nrow_local=nrow_local, ncol_local=ncol_local, &
453 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
454 CALL scale_complex_spectral(preconditioner_env, local_data(1:nrow_local, 1:ncol_local), &
455 row_indices, col_indices)
457 matrix_spectral,
z_zero, matrix_out)
460 END SUBROUTINE apply_complex_spectral
471 matrix_out_re, matrix_out_im)
474 TYPE(
dbcsr_type),
TARGET :: matrix_in_re, matrix_in_im, &
475 matrix_out_re, matrix_out_im
477 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_preconditioner_dbcsr_complex'
479 INTEGER :: handle, k, n
482 TYPE(
cp_fm_type) :: matrix_in_im_fm, matrix_in_re_fm, &
483 matrix_out_im_fm, matrix_out_re_fm
487 preconditioners(1)%preconditioner => preconditioner_env
488 input(1, 1)%matrix => matrix_in_re
489 input(2, 1)%matrix => matrix_in_im
490 output(1, 1)%matrix => matrix_out_re
491 output(2, 1)%matrix => matrix_out_im
495 CALL timeset(routinen, handle)
497 CALL dbcsr_get_info(matrix_in_re, nfullrows_total=n, nfullcols_total=k)
498 cpassert(
ASSOCIATED(preconditioner_env%complex_fm))
500 CALL cp_fm_create(matrix_in_re_fm, preconditioner_env%complex_fm%matrix_struct, &
501 nrow=n, ncol=k, name=
'complex preconditioner input real')
502 CALL cp_fm_create(matrix_in_im_fm, preconditioner_env%complex_fm%matrix_struct, &
503 nrow=n, ncol=k, name=
'complex preconditioner input imaginary')
504 CALL cp_fm_create(matrix_out_re_fm, preconditioner_env%complex_fm%matrix_struct, &
505 nrow=n, ncol=k, name=
'complex preconditioner output real')
506 CALL cp_fm_create(matrix_out_im_fm, preconditioner_env%complex_fm%matrix_struct, &
507 nrow=n, ncol=k, name=
'complex preconditioner output imaginary')
511 CALL cp_cfm_create(matrix_in, matrix_in_re_fm%matrix_struct, &
512 name=
'complex preconditioner input')
513 CALL cp_cfm_create(matrix_out, matrix_in_re_fm%matrix_struct, &
514 name=
'complex preconditioner output')
515 CALL cp_fm_to_cfm(matrix_in_re_fm, matrix_in_im_fm, matrix_in)
517 CALL cp_cfm_to_fm(matrix_out, matrix_out_re_fm, matrix_out_im_fm)
530 CALL timestop(handle)
540 SUBROUTINE apply_full_single(preconditioner_env, matrix_in, matrix_out)
543 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
545 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_full_single'
547 INTEGER :: handle, k, n
549 CALL timeset(routinen, handle)
552 CALL parallel_gemm(
'N',
'N', n, k, n, 1.0_dp, preconditioner_env%fm, &
553 matrix_in, 0.0_dp, matrix_out)
554 CALL timestop(handle)
556 END SUBROUTINE apply_full_single
564 SUBROUTINE apply_single(preconditioner_env, matrix_in, matrix_out)
569 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_single'
573 CALL timeset(routinen, handle)
575 IF (.NOT.
ASSOCIATED(preconditioner_env%dbcsr_matrix))
THEN
576 cpabort(
"NOT ASSOCIATED preconditioner_env%dbcsr_matrix")
578 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, matrix_in, &
581 CALL timestop(handle)
583 END SUBROUTINE apply_single
592 SUBROUTINE apply_full_direct(preconditioner_env, matrix_in, matrix_out)
595 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
597 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_full_direct'
599 INTEGER :: handle, k, n
602 CALL timeset(routinen, handle)
605 CALL cp_fm_create(work, matrix_in%matrix_struct, name=
"apply_full_single")
607 &
"SOLVE", transa=
"T")
609 &
"SOLVE", transa=
"N")
612 CALL timestop(handle)
614 END SUBROUTINE apply_full_direct
622 SUBROUTINE apply_chebyshev_fm(preconditioner_env, matrix_in, matrix_out)
625 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
627 INTEGER ::
degree, iteration, k, n
628 REAL(kind=
dp) :: delta, rho, rho_previous, sigma, theta
631 cpassert(
ASSOCIATED(preconditioner_env%fm))
632 degree = preconditioner_env%polynomial_degree
634 theta = 0.5_dp*(preconditioner_env%polynomial_max + preconditioner_env%polynomial_min)
635 delta = 0.5_dp*(preconditioner_env%polynomial_max - preconditioner_env%polynomial_min)
637 rho_previous = 1.0_dp/sigma
639 CALL cp_fm_create(direction, matrix_in%matrix_struct, name=
'Chebyshev direction')
640 CALL cp_fm_create(residual, matrix_in%matrix_struct, name=
'Chebyshev residual')
646 CALL parallel_gemm(
'N',
'N', n, k, n, -1.0_dp, preconditioner_env%fm, &
647 matrix_out, 1.0_dp, residual)
648 rho = 1.0_dp/(2.0_dp*sigma - rho_previous)
657 END SUBROUTINE apply_chebyshev_fm
665 SUBROUTINE apply_chebyshev_dbcsr(preconditioner_env, matrix_in, matrix_out)
670 INTEGER ::
degree, iteration
671 REAL(kind=
dp) :: delta, rho, rho_previous, sigma, theta
674 cpassert(
ASSOCIATED(preconditioner_env%dbcsr_matrix))
675 degree = preconditioner_env%polynomial_degree
677 theta = 0.5_dp*(preconditioner_env%polynomial_max + preconditioner_env%polynomial_min)
678 delta = 0.5_dp*(preconditioner_env%polynomial_max - preconditioner_env%polynomial_min)
680 rho_previous = 1.0_dp/sigma
681 CALL dbcsr_copy(direction, matrix_in, name=
'Chebyshev direction')
682 CALL dbcsr_copy(residual, matrix_in, name=
'Chebyshev residual')
684 CALL dbcsr_add(matrix_out, direction, 1.0_dp, 1.0_dp/theta)
686 CALL dbcsr_add(direction, matrix_in, 1.0_dp, 1.0_dp/theta)
689 CALL dbcsr_add(residual, matrix_in, 1.0_dp, 1.0_dp)
690 CALL dbcsr_multiply(
'N',
'N', -1.0_dp, preconditioner_env%dbcsr_matrix, &
691 matrix_out, 1.0_dp, residual)
692 rho = 1.0_dp/(2.0_dp*sigma - rho_previous)
693 CALL dbcsr_add(direction, residual, rho*rho_previous, 2.0_dp*rho/delta)
694 CALL dbcsr_add(matrix_out, direction, 1.0_dp, 1.0_dp)
700 END SUBROUTINE apply_chebyshev_dbcsr
708 SUBROUTINE apply_low_rank_fm(preconditioner_env, matrix_in, matrix_out)
711 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
713 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_low_rank_fm'
715 INTEGER :: handle, i, j, k, n, ncol_local, nocc, &
716 nrow_local, rank_used
717 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
718 REAL(kind=
dp) :: correction
719 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
720 POINTER :: local_data
723 CALL timeset(routinen, handle)
725 cpassert(
ASSOCIATED(preconditioner_env%fm))
726 cpassert(
ASSOCIATED(preconditioner_env%full_evals))
727 cpassert(
ASSOCIATED(preconditioner_env%occ_evals))
730 nocc =
SIZE(preconditioner_env%occ_evals)
731 cpassert(n ==
SIZE(preconditioner_env%full_evals))
732 rank_used = min(preconditioner_env%spectral_rank, n - nocc)
739 SELECT CASE (preconditioner_env%low_rank_base)
741 cpassert(
ASSOCIATED(preconditioner_env%base_fm))
742 CALL parallel_gemm(
'N',
'N', n, k, n, preconditioner_env%spectral_base_scale, &
743 preconditioner_env%base_fm, matrix_in, 0.0_dp, matrix_out)
745 CALL apply_lattice_operator_fm(preconditioner_env, matrix_in, matrix_out, &
746 preconditioner_env%spectral_base_scale)
748 cpabort(
"Unknown FERMI_LOW_RANK base operator during application")
751 IF (rank_used > 0)
THEN
752 CALL cp_fm_create(matrix_tmp, matrix_in%matrix_struct, name=routinen, &
753 nrow=rank_used, ncol=k)
754 CALL cp_fm_get_info(matrix_tmp, nrow_local=nrow_local, ncol_local=ncol_local, &
755 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
757 CALL parallel_gemm(
'T',
'N', rank_used, k, n, 1.0_dp, preconditioner_env%fm, &
758 matrix_in, 0.0_dp, matrix_tmp, a_first_col=nocc + 1)
763 preconditioner_env%full_evals(nocc + row_indices(i)), &
764 preconditioner_env%spectral_reference, &
765 preconditioner_env%energy_gap) &
766 - preconditioner_env%spectral_base_scale
767 local_data(i, j) = local_data(i, j)*correction
771 CALL parallel_gemm(
'N',
'N', n, k, rank_used, 1.0_dp, preconditioner_env%fm, &
772 matrix_tmp, 1.0_dp, matrix_out, a_first_col=nocc + 1)
776 CALL timestop(handle)
778 END SUBROUTINE apply_low_rank_fm
787 SUBROUTINE apply_lattice_operator_fm(preconditioner_env, matrix_in, matrix_out, scale_factor)
790 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
791 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: scale_factor
793 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_lattice_operator_fm'
795 INTEGER :: fft_ok, handle, i
797 REAL(kind=
dp) :: imaginary_residual, output_max, scale
798 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: base_input, coarse_projected, &
799 coarse_residual, coarse_rhs, &
800 local_input, local_output
802 CALL timeset(routinen, handle)
803 cpassert(
ALLOCATED(preconditioner_env%lattice_inverse_k))
805 IF (
PRESENT(scale_factor)) scale = scale_factor
806 CALL distribute_lattice_rhs(preconditioner_env, matrix_in, &
807 preconditioner_env%lattice_rhs_distribution, local_input)
808 ALLOCATE (local_output(
SIZE(local_input, 1),
SIZE(local_input, 2)))
809 IF (
ALLOCATED(preconditioner_env%lattice_local_indices))
THEN
810 cpassert(
ALLOCATED(preconditioner_env%lattice_local_operator))
811 cpassert(
ALLOCATED(preconditioner_env%lattice_local_coarse_inverse))
812 ALLOCATE (base_input(
SIZE(local_input, 1),
SIZE(local_input, 2)), &
813 coarse_projected(
SIZE(preconditioner_env%lattice_local_indices),
SIZE(local_input, 2)), &
814 coarse_rhs(
SIZE(preconditioner_env%lattice_local_indices),
SIZE(local_input, 2)))
815 DO i = 1,
SIZE(preconditioner_env%lattice_local_indices)
816 coarse_projected(i, :) = local_input(preconditioner_env%lattice_local_indices(i), :)
818 coarse_rhs(:, :) = matmul(preconditioner_env%lattice_local_coarse_inverse, &
820 base_input(:, :) = local_input - &
821 matmul(preconditioner_env%lattice_local_operator, coarse_rhs)
823 ALLOCATE (base_input(
SIZE(local_input, 1),
SIZE(local_input, 2)), source=local_input)
826 imaginary_residual = 0.0_dp
827 IF (
SIZE(local_input, 2) > 0)
THEN
829 preconditioner_env%lattice_dims, base_input, local_output, &
830 used_fft, imaginary_residual)
832 IF (
ALLOCATED(preconditioner_env%lattice_local_indices))
THEN
833 ALLOCATE (coarse_residual(
SIZE(coarse_rhs, 1),
SIZE(coarse_rhs, 2)))
834 coarse_projected(:, :) = matmul(transpose(preconditioner_env%lattice_local_operator), &
836 coarse_residual(:, :) = matmul(preconditioner_env%lattice_local_coarse_inverse, &
838 local_output(preconditioner_env%lattice_local_indices, :) = &
839 local_output(preconditioner_env%lattice_local_indices, :) + coarse_rhs - coarse_residual
840 DEALLOCATE (coarse_projected, coarse_residual, coarse_rhs)
842 fft_ok = merge(1, 0, used_fft)
844 IF (
SIZE(local_output) > 0) output_max = maxval(abs(local_output))
845 CALL preconditioner_env%para_env%min(fft_ok)
846 CALL preconditioner_env%para_env%max(imaginary_residual)
847 CALL preconditioner_env%para_env%max(output_max)
848 IF (fft_ok == 0) cpabort(
"Lattice preconditioner inverse failed to use FFTs")
849 IF (imaginary_residual > 1.0e-10_dp*max(1.0_dp, output_max))
THEN
850 cpabort(
"Lattice preconditioner inverse produced a non-real Gamma-point result")
852 CALL collect_lattice_rhs(preconditioner_env, preconditioner_env%lattice_rhs_distribution, &
853 local_output, matrix_out, scale)
854 DEALLOCATE (base_input, local_input, local_output)
855 CALL timestop(handle)
857 END SUBROUTINE apply_lattice_operator_fm
865 SUBROUTINE apply_lattice_state_operator_fm(preconditioner_env, matrix_in, matrix_out)
868 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
870 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_lattice_state_operator_fm'
872 INTEGER :: fft_ok, global_column, handle, i, j, k, &
875 REAL(kind=
dp) :: imaginary_residual, output_max
876 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: base_input, coarse_projected, &
877 coarse_residual, coarse_rhs, complement_input, local_input, local_output, &
878 occupied_component, occupied_update
880 CALL timeset(routinen, handle)
881 cpassert(
ALLOCATED(preconditioner_env%lattice_state_inverse_k))
883 cpassert(
SIZE(preconditioner_env%lattice_state_inverse_k, 4) == k)
884 CALL distribute_lattice_rhs(preconditioner_env, matrix_in, &
885 preconditioner_env%lattice_rhs_distribution, local_input)
886 cpassert(
ALLOCATED(preconditioner_env%lattice_occ_vectors))
887 cpassert(
ALLOCATED(preconditioner_env%lattice_occ_dual))
888 ALLOCATE (complement_input(n,
SIZE(local_input, 2)), &
889 local_output(n,
SIZE(local_input, 2)), &
890 occupied_component(k,
SIZE(local_input, 2)), &
891 occupied_update(n,
SIZE(local_input, 2)))
892 occupied_component(:, :) = matmul(transpose(preconditioner_env%lattice_occ_vectors), &
894 complement_input(:, :) = local_input - &
895 matmul(preconditioner_env%lattice_occ_dual, occupied_component)
896 ALLOCATE (base_input(n,
SIZE(local_input, 2)), source=complement_input)
897 IF (
ALLOCATED(preconditioner_env%lattice_state_local_indices))
THEN
898 cpassert(
ALLOCATED(preconditioner_env%lattice_state_local_operator))
899 cpassert(
ALLOCATED(preconditioner_env%lattice_state_local_coarse_inverse))
900 ALLOCATE (coarse_rhs(
SIZE(preconditioner_env%lattice_state_local_indices, 1), &
901 SIZE(local_input, 2)), &
902 coarse_projected(
SIZE(preconditioner_env%lattice_state_local_indices, 1), &
903 SIZE(local_input, 2)))
904 DO j = 1,
SIZE(local_input, 2)
905 state = preconditioner_env%lattice_rhs_distribution%global_columns(j)
906 DO i = 1,
SIZE(preconditioner_env%lattice_state_local_indices, 1)
907 coarse_projected(i, j) = &
908 complement_input(preconditioner_env%lattice_state_local_indices(i, state), j)
910 coarse_rhs(:, j) = matmul( &
911 preconditioner_env%lattice_state_local_coarse_inverse(:, :, state), &
912 coarse_projected(:, j))
913 base_input(:, j) = complement_input(:, j) - &
914 matmul(preconditioner_env%lattice_state_local_operator(:, :, state), &
919 imaginary_residual = 0.0_dp
920 IF (
SIZE(local_input, 2) > 0)
THEN
922 preconditioner_env%lattice_dims, &
923 base_input, local_output, used_fft, imaginary_residual, &
924 preconditioner_env%lattice_rhs_distribution%global_columns)
926 IF (
ALLOCATED(preconditioner_env%lattice_state_local_indices))
THEN
927 ALLOCATE (coarse_residual(
SIZE(coarse_rhs, 1),
SIZE(coarse_rhs, 2)))
928 DO j = 1,
SIZE(local_input, 2)
929 state = preconditioner_env%lattice_rhs_distribution%global_columns(j)
930 coarse_projected(:, j) = &
931 matmul(transpose(preconditioner_env%lattice_state_local_operator(:, :, state)), &
933 coarse_residual(:, j) = matmul( &
934 preconditioner_env%lattice_state_local_coarse_inverse(:, :, state), &
935 coarse_projected(:, j))
936 local_output(preconditioner_env%lattice_state_local_indices(:, state), j) = &
937 local_output(preconditioner_env%lattice_state_local_indices(:, state), j) + &
938 coarse_rhs(:, j) - coarse_residual(:, j)
940 DEALLOCATE (coarse_projected, coarse_residual, coarse_rhs)
942 fft_ok = merge(1, 0, used_fft)
944 IF (
SIZE(local_output) > 0) output_max = maxval(abs(local_output))
945 CALL preconditioner_env%para_env%min(fft_ok)
946 CALL preconditioner_env%para_env%max(imaginary_residual)
947 CALL preconditioner_env%para_env%max(output_max)
948 IF (fft_ok == 0)
THEN
949 cpabort(
"State-dependent lattice preconditioner inverse failed to use FFTs")
951 IF (imaginary_residual > 1.0e-10_dp*max(1.0_dp, output_max))
THEN
952 cpabort(
"State-dependent lattice preconditioner produced a non-real Gamma-point result")
954 occupied_component(:, :) = matmul(transpose(preconditioner_env%lattice_occ_dual), &
956 occupied_update(:, :) = matmul(preconditioner_env%lattice_occ_vectors, occupied_component)
957 local_output(:, :) = local_output - occupied_update
958 occupied_component(:, :) = matmul(transpose(preconditioner_env%lattice_occ_vectors), &
960 DO j = 1,
SIZE(local_input, 2)
961 global_column = preconditioner_env%lattice_rhs_distribution%global_columns(j)
963 occupied_component(i, j) = occupied_component(i, j)/max( &
964 preconditioner_env%energy_gap, &
965 preconditioner_env%full_evals(i) - &
966 preconditioner_env%occ_evals(global_column))
969 occupied_update(:, :) = matmul(preconditioner_env%lattice_occ_vectors, occupied_component)
970 local_output(:, :) = local_output + occupied_update
971 CALL collect_lattice_rhs(preconditioner_env, preconditioner_env%lattice_rhs_distribution, &
972 local_output, matrix_out)
973 DEALLOCATE (base_input, complement_input, local_input, local_output, occupied_component, occupied_update)
974 CALL timestop(handle)
976 END SUBROUTINE apply_lattice_state_operator_fm
985 SUBROUTINE distribute_lattice_rhs(preconditioner_env, matrix_in, distribution, local_input)
990 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
991 INTENT(OUT) :: local_input
993 INTEGER :: destination, i, ientry, j, k, n, &
994 ncol_local, nowned, nrow_local, &
996 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: cursor, send_global_columns, &
998 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1000 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: recv_values, send_values
1001 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
1002 POINTER :: input_data
1004 num_pe = preconditioner_env%para_env%num_pe
1006 nrow_local=nrow_local, ncol_local=ncol_local, &
1007 row_indices=row_indices, col_indices=col_indices, local_data=input_data)
1008 rebuild = distribution%nrow_global /= n .OR. distribution%ncol_global /= k .OR. &
1009 distribution%nrow_local /= nrow_local .OR. distribution%ncol_local /= ncol_local .OR. &
1010 distribution%num_pe /= num_pe
1011 IF (.NOT. rebuild)
THEN
1012 rebuild = .NOT.
ALLOCATED(distribution%local_rows) .OR. &
1013 .NOT.
ALLOCATED(distribution%local_columns)
1015 IF (.NOT. rebuild)
THEN
1016 rebuild = any(distribution%local_rows /= row_indices) .OR. &
1017 any(distribution%local_columns /= col_indices)
1021 distribution%nrow_global = n
1022 distribution%ncol_global = k
1023 distribution%nrow_local = nrow_local
1024 distribution%ncol_local = ncol_local
1025 distribution%num_pe = num_pe
1026 ALLOCATE (distribution%local_rows(nrow_local), distribution%local_columns(ncol_local))
1027 distribution%local_rows(:) = row_indices
1028 distribution%local_columns(:) = col_indices
1029 ALLOCATE (distribution%send_counts(num_pe), distribution%send_displacements(num_pe), &
1030 distribution%recv_counts(num_pe), distribution%recv_displacements(num_pe), &
1032 distribution%send_counts = 0
1033 DO j = 1, ncol_local
1034 destination =
modulo(col_indices(j) - 1, num_pe) + 1
1035 distribution%send_counts(destination) = &
1036 distribution%send_counts(destination) + nrow_local
1038 CALL preconditioner_env%para_env%alltoall(distribution%send_counts, &
1039 distribution%recv_counts, 1)
1040 distribution%send_displacements(1) = 0
1041 distribution%recv_displacements(1) = 0
1043 distribution%send_displacements(i) = distribution%send_displacements(i - 1) + &
1044 distribution%send_counts(i - 1)
1045 distribution%recv_displacements(i) = distribution%recv_displacements(i - 1) + &
1046 distribution%recv_counts(i - 1)
1049 ALLOCATE (send_global_rows(sum(distribution%send_counts)), &
1050 send_global_columns(sum(distribution%send_counts)), &
1051 distribution%send_local_rows(sum(distribution%send_counts)), &
1052 distribution%send_local_columns(sum(distribution%send_counts)), &
1053 distribution%recv_global_rows(sum(distribution%recv_counts)), &
1054 distribution%recv_global_columns(sum(distribution%recv_counts)))
1055 cursor(:) = distribution%send_displacements
1056 DO j = 1, ncol_local
1057 destination =
modulo(col_indices(j) - 1, num_pe) + 1
1058 DO i = 1, nrow_local
1059 cursor(destination) = cursor(destination) + 1
1060 ientry = cursor(destination)
1061 send_global_rows(ientry) = row_indices(i)
1062 send_global_columns(ientry) = col_indices(j)
1063 distribution%send_local_rows(ientry) = i
1064 distribution%send_local_columns(ientry) = j
1067 CALL preconditioner_env%para_env%alltoall( &
1068 send_global_rows, distribution%send_counts, distribution%send_displacements, &
1069 distribution%recv_global_rows, distribution%recv_counts, distribution%recv_displacements)
1070 CALL preconditioner_env%para_env%alltoall( &
1071 send_global_columns, distribution%send_counts, distribution%send_displacements, &
1072 distribution%recv_global_columns, distribution%recv_counts, distribution%recv_displacements)
1075 DO j = preconditioner_env%para_env%mepos + 1, k, num_pe
1078 ALLOCATE (distribution%global_columns(nowned))
1080 DO j = preconditioner_env%para_env%mepos + 1, k, num_pe
1082 distribution%global_columns(nowned) = j
1084 DEALLOCATE (cursor, send_global_columns, send_global_rows)
1087 nowned =
SIZE(distribution%global_columns)
1088 ALLOCATE (local_input(n, nowned), source=0.0_dp)
1089 ALLOCATE (send_values(sum(distribution%send_counts)), &
1090 recv_values(sum(distribution%recv_counts)))
1091 DO ientry = 1,
SIZE(send_values)
1092 send_values(ientry) = input_data(distribution%send_local_rows(ientry), &
1093 distribution%send_local_columns(ientry))
1095 CALL preconditioner_env%para_env%alltoall( &
1096 send_values, distribution%send_counts, distribution%send_displacements, &
1097 recv_values, distribution%recv_counts, distribution%recv_displacements)
1098 DO ientry = 1,
SIZE(recv_values)
1099 slot = (distribution%recv_global_columns(ientry) - 1)/num_pe + 1
1100 local_input(distribution%recv_global_rows(ientry), slot) = recv_values(ientry)
1103 DEALLOCATE (recv_values, send_values)
1105 END SUBROUTINE distribute_lattice_rhs
1115 SUBROUTINE collect_lattice_rhs(preconditioner_env, distribution, local_output, matrix_out, scale_factor)
1119 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: local_output
1121 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: scale_factor
1123 INTEGER :: ientry, num_pe, slot
1124 REAL(kind=
dp) :: scale
1125 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: recv_values, send_values
1126 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
1127 POINTER :: output_data
1129 num_pe = preconditioner_env%para_env%num_pe
1130 cpassert(
SIZE(local_output, 1) == distribution%nrow_global)
1131 cpassert(
SIZE(local_output, 2) ==
SIZE(distribution%global_columns))
1133 IF (
PRESENT(scale_factor)) scale = scale_factor
1134 ALLOCATE (send_values(sum(distribution%recv_counts)), &
1135 recv_values(sum(distribution%send_counts)))
1136 DO ientry = 1,
SIZE(send_values)
1137 slot = (distribution%recv_global_columns(ientry) - 1)/num_pe + 1
1138 send_values(ientry) = local_output(distribution%recv_global_rows(ientry), slot)
1140 CALL preconditioner_env%para_env%alltoall( &
1141 send_values, distribution%recv_counts, distribution%recv_displacements, &
1142 recv_values, distribution%send_counts, distribution%send_displacements)
1145 output_data = 0.0_dp
1146 DO ientry = 1,
SIZE(recv_values)
1147 output_data(distribution%send_local_rows(ientry), &
1148 distribution%send_local_columns(ientry)) = scale*recv_values(ientry)
1150 DEALLOCATE (recv_values, send_values)
1152 END SUBROUTINE collect_lattice_rhs
1160 SUBROUTINE apply_lattice_operator_dbcsr(preconditioner_env, matrix_in, matrix_out)
1170 CALL dbcsr_get_info(matrix_in, nfullrows_total=n, nfullcols_total=k)
1172 context=preconditioner_env%ctxt, &
1173 para_env=preconditioner_env%para_env)
1174 CALL cp_fm_create(input_fm, fm_struct, name=
"lattice preconditioner input")
1175 CALL cp_fm_create(output_fm, fm_struct, name=
"lattice preconditioner output")
1178 CALL apply_lattice_operator_fm(preconditioner_env, input_fm, output_fm)
1183 END SUBROUTINE apply_lattice_operator_dbcsr
1191 SUBROUTINE apply_low_rank_dbcsr(preconditioner_env, matrix_in, matrix_out)
1196 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_low_rank_dbcsr'
1198 INTEGER :: col, col_offset, col_size, handle, i, j, &
1199 k, n, nocc, rank_used, row, &
1200 row_offset, row_size
1201 REAL(kind=
dp) :: correction
1202 REAL(kind=
dp),
DIMENSION(:, :),
POINTER ::
DATA
1206 CALL timeset(routinen, handle)
1209 CALL apply_low_rank_dbcsr_via_fm(preconditioner_env, matrix_in, matrix_out)
1210 CALL timestop(handle)
1214 cpassert(
ASSOCIATED(preconditioner_env%base_dbcsr_matrix))
1215 cpassert(
ASSOCIATED(preconditioner_env%dbcsr_matrix))
1216 cpassert(
ASSOCIATED(preconditioner_env%full_evals))
1217 cpassert(
ASSOCIATED(preconditioner_env%occ_evals))
1219 CALL dbcsr_get_info(matrix_in, nfullrows_total=n, nfullcols_total=k)
1220 nocc =
SIZE(preconditioner_env%occ_evals)
1221 cpassert(n ==
SIZE(preconditioner_env%full_evals))
1222 rank_used = min(preconditioner_env%spectral_rank, n - nocc)
1225 CALL dbcsr_multiply(
'N',
'N', preconditioner_env%spectral_base_scale, &
1226 preconditioner_env%base_dbcsr_matrix, matrix_in, 0.0_dp, matrix_out)
1228 IF (rank_used > 0)
THEN
1229 CALL dbcsr_copy(matrix_tmp, matrix_in, name=routinen)
1231 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
1232 matrix_in, 0.0_dp, matrix_tmp, &
1233 first_row=nocc + 1, last_row=nocc + rank_used)
1238 row_size=row_size, col_size=col_size, &
1239 row_offset=row_offset, col_offset=col_offset)
1242 IF (row_offset + i - 1 >= nocc + 1 .AND. &
1243 row_offset + i - 1 <= nocc + rank_used)
THEN
1245 preconditioner_env%full_evals(row_offset + i - 1), &
1246 preconditioner_env%spectral_reference, &
1247 preconditioner_env%energy_gap) &
1248 - preconditioner_env%spectral_base_scale
1249 DATA(i, j) =
DATA(i, j)*correction
1256 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
1257 matrix_tmp, 1.0_dp, matrix_out, &
1258 first_k=nocc + 1, last_k=nocc + rank_used)
1262 CALL timestop(handle)
1264 END SUBROUTINE apply_low_rank_dbcsr
1272 SUBROUTINE apply_low_rank_dbcsr_via_fm(preconditioner_env, matrix_in, matrix_out)
1282 CALL dbcsr_get_info(matrix_in, nfullrows_total=n, nfullcols_total=k)
1284 context=preconditioner_env%ctxt, &
1285 para_env=preconditioner_env%para_env)
1286 CALL cp_fm_create(input_fm, fm_struct, name=
"lattice low-rank input")
1287 CALL cp_fm_create(output_fm, fm_struct, name=
"lattice low-rank output")
1290 CALL apply_low_rank_fm(preconditioner_env, input_fm, output_fm)
1295 END SUBROUTINE apply_low_rank_dbcsr_via_fm
1303 SUBROUTINE apply_full_all(preconditioner_env, matrix_in, matrix_out)
1306 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
1308 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_full_all'
1310 INTEGER :: handle, i, j, k, n, ncol_local, &
1312 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1313 REAL(kind=
dp) :: dum
1314 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
1315 POINTER :: local_data
1318 CALL timeset(routinen, handle)
1322 CALL cp_fm_create(matrix_tmp, matrix_in%matrix_struct, name=
"apply_full_all")
1323 CALL cp_fm_get_info(matrix_tmp, nrow_local=nrow_local, ncol_local=ncol_local, &
1324 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
1327 CALL parallel_gemm(
'T',
'N', n, k, n, 1.0_dp, preconditioner_env%fm, &
1328 matrix_in, 0.0_dp, matrix_tmp)
1331 DO j = 1, ncol_local
1332 DO i = 1, nrow_local
1333 dum = 1.0_dp/max(preconditioner_env%energy_gap, &
1334 preconditioner_env%full_evals(row_indices(i)) - preconditioner_env%occ_evals(col_indices(j)))
1335 local_data(i, j) = local_data(i, j)*dum
1340 CALL parallel_gemm(
'N',
'N', n, k, n, 1.0_dp, preconditioner_env%fm, &
1341 matrix_tmp, 0.0_dp, matrix_out)
1345 CALL timestop(handle)
1347 END SUBROUTINE apply_full_all
1355 SUBROUTINE apply_all(preconditioner_env, matrix_in, matrix_out)
1360 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_all'
1362 INTEGER :: col, col_offset, col_size, handle, i, j, &
1363 row, row_offset, row_size
1364 REAL(kind=
dp) :: dum
1365 REAL(kind=
dp),
DIMENSION(:, :),
POINTER ::
DATA
1369 CALL timeset(routinen, handle)
1371 CALL dbcsr_copy(matrix_tmp, matrix_in, name=
"apply_full_all")
1372 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
1373 matrix_in, 0.0_dp, matrix_tmp)
1378 row_size=row_size, col_size=col_size, &
1379 row_offset=row_offset, col_offset=col_offset)
1382 dum = 1.0_dp/max(preconditioner_env%energy_gap, &
1383 preconditioner_env%full_evals(row_offset + i - 1) &
1384 - preconditioner_env%occ_evals(col_offset + j - 1))
1385 DATA(i, j) =
DATA(i, j)*dum
1392 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
1393 matrix_tmp, 0.0_dp, matrix_out)
1395 CALL timestop(handle)
1397 END SUBROUTINE apply_all
1405 SUBROUTINE apply_full_all_covariant(preconditioner_env, matrix_in, matrix_out)
1408 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
1410 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_full_all_covariant'
1412 INTEGER :: handle, k, n
1413 TYPE(
cp_fm_type) :: canonical_in, canonical_out
1415 CALL timeset(routinen, handle)
1416 cpassert(
ASSOCIATED(preconditioner_env%occ_rotation))
1419 CALL cp_fm_create(canonical_in, matrix_in%matrix_struct, name=routinen)
1420 CALL cp_fm_create(canonical_out, matrix_out%matrix_struct, name=routinen)
1422 preconditioner_env%occ_rotation, 0.0_dp, canonical_in)
1423 IF (preconditioner_env%lattice_fft_active)
THEN
1424 CALL apply_lattice_state_operator_fm(preconditioner_env, canonical_in, canonical_out)
1426 CALL apply_full_all(preconditioner_env, canonical_in, canonical_out)
1428 CALL parallel_gemm(
'N',
'T', n, k, k, 1.0_dp, canonical_out, &
1429 preconditioner_env%occ_rotation, 0.0_dp, matrix_out)
1432 CALL timestop(handle)
1434 END SUBROUTINE apply_full_all_covariant
1442 SUBROUTINE apply_all_covariant(preconditioner_env, matrix_in, matrix_out)
1447 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_all_covariant'
1449 INTEGER :: handle, k, n
1452 TYPE(
dbcsr_type) :: canonical_in, canonical_out
1454 CALL timeset(routinen, handle)
1455 cpassert(
ASSOCIATED(preconditioner_env%occ_rotation))
1456 CALL dbcsr_get_info(matrix_in, nfullrows_total=n, nfullcols_total=k)
1458 IF (preconditioner_env%lattice_fft_active)
THEN
1461 context=preconditioner_env%ctxt, &
1462 para_env=preconditioner_env%para_env)
1467 CALL apply_full_all_covariant(preconditioner_env, input_fm, output_fm)
1471 CALL timestop(handle)
1475 IF (.NOT.
ASSOCIATED(preconditioner_env%occ_rotation_dbcsr))
THEN
1476 CALL dbcsr_init_p(preconditioner_env%occ_rotation_dbcsr)
1478 template=matrix_in, m=k, n=k, &
1479 sym=dbcsr_type_no_symmetry)
1481 preconditioner_env%occ_rotation_dbcsr)
1484 CALL dbcsr_copy(canonical_in, matrix_in, name=routinen)
1486 CALL dbcsr_copy(canonical_out, matrix_out, name=routinen)
1489 preconditioner_env%occ_rotation_dbcsr, 0.0_dp, canonical_in)
1490 CALL apply_all(preconditioner_env, canonical_in, canonical_out)
1492 preconditioner_env%occ_rotation_dbcsr, 0.0_dp, matrix_out)
1495 CALL timestop(handle)
1497 END SUBROUTINE apply_all_covariant
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_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)
Performs one of the matrix-matrix operations: matrix_c = alpha * op1( matrix_a ) * op2( matrix_b ) + ...
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
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_init_p(matrix)
...
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_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan, check_plan)
Copy a DBCSR matrix to a BLACS matrix.
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 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_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
subroutine, public cp_fm_scale(alpha, matrix_a)
scales a matrix matrix_a = alpha * matrix_b
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_restore(fm_matrix, neig, fm_matrixb, fm_matrixout, op, pos, transa)
apply Cholesky decomposition op can be "SOLVE" (out = U^-1 * in) or "MULTIPLY" (out = U * in) pos can...
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
Defines the basic variable types.
integer, parameter, public dp
Block-circulant inverse operators for replicated-cell OT preconditioners.
subroutine, public apply_lattice_inverse_dense(inverse_k, lattice_dims, matrix_in, matrix_out, used_fft, imaginary_residual)
Apply inverse Fourier blocks to a dense cell-major real matrix.
subroutine, public apply_lattice_state_inverse_dense(inverse_k, lattice_dims, matrix_in, matrix_out, used_fft, imaginary_residual, state_indices)
Apply one inverse Fourier operator to every column of a dense real matrix.
integer, parameter, public local_gemm_pu_gpu
Small algebraic helpers for the rotationally covariant low-rank OT preconditioner.
pure elemental real(kind=dp) function, public low_rank_inverse_weight(eigenvalue, reference, energy_gap)
Spectral inverse weight relative to a common occupied reference level.
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
real(kind=dp), parameter, public degree
complex(kind=dp), parameter, public z_zero
basic linear algebra operations for full matrixes
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public apply_preconditioner_dbcsr_complex(preconditioner_env, matrix_in_re, matrix_in_im, matrix_out_re, matrix_out_im)
Apply a complex orbital preconditioner to paired real/imaginary DBCSR matrices.
subroutine, public apply_preconditioner_fm(preconditioner_env, matrix_in, matrix_out)
applies a previously created preconditioner to a full matrix
subroutine, public apply_preconditioner_cfm_complex(preconditioner_env, matrix_in, matrix_out)
Apply a complex k-point orbital preconditioner.
subroutine, public apply_preconditioner_dbcsr(preconditioner_env, matrix_in, matrix_out)
...
subroutine, public apply_preconditioner_complex_batch(preconditioners, matrix_in, matrix_out, handled, output_scale)
Apply single-rank complex preconditioners in bounded OpenMP batches. Packing and DBCSR writeback stay...
subroutine, public release_lattice_rhs_distribution(distribution)
Release a cached lattice right-hand-side communication map.
Represent a complex full matrix.
keeps the information about the structure of a full matrix