32#if defined (__HAS_IEEE_EXCEPTIONS)
33 USE ieee_exceptions,
ONLY: ieee_get_halting_mode, &
34 ieee_set_halting_mode, &
37#include "../base/base_uses.f90"
42 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
43 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_fm_basic_linalg'
77 REAL(KIND=
dp),
EXTERNAL :: dlange, pdlange, pdlatra
78 REAL(KIND=
sp),
EXTERNAL :: slange, pslange, pslatra
81 MODULE PROCEDURE cp_fm_trace_a0b0t0
82 MODULE PROCEDURE cp_fm_trace_a1b0t1_a
83 MODULE PROCEDURE cp_fm_trace_a1b0t1_p
84 MODULE PROCEDURE cp_fm_trace_a1b1t1_aa
85 MODULE PROCEDURE cp_fm_trace_a1b1t1_ap
86 MODULE PROCEDURE cp_fm_trace_a1b1t1_pa
87 MODULE PROCEDURE cp_fm_trace_a1b1t1_pp
91 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_aa
92 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_ap
93 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_pa
94 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_pp
105 REAL(kind=
dp),
INTENT(OUT) :: det_a
106 REAL(kind=
dp) :: determinant
108 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
109 INTEGER :: n, i, info, p
110 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
111 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
diag
113#if defined(__parallel)
114 INTEGER :: myprow, nprow, npcol, nrow_local, nrow_block, irow_local
115 INTEGER,
DIMENSION(9) :: desca
119 matrix_struct=matrix_a%matrix_struct, &
123 a => matrix_lu%local_data
124 n = matrix_lu%matrix_struct%nrow_global
130#if defined(__parallel)
132 desca(:) = matrix_lu%matrix_struct%descriptor(:)
133 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
135 determinant = product(
diag)
136 myprow = matrix_lu%matrix_struct%context%mepos(1)
137 nprow = matrix_lu%matrix_struct%context%num_pe(1)
138 npcol = matrix_lu%matrix_struct%context%num_pe(2)
139 nrow_local = matrix_lu%matrix_struct%nrow_locals(myprow)
140 nrow_block = matrix_lu%matrix_struct%nrow_block
141 DO irow_local = 1, nrow_local
142 i = matrix_lu%matrix_struct%row_indices(irow_local)
143 IF (ipivot(irow_local) /= i) p = p + 1
145 CALL matrix_lu%matrix_struct%para_env%sum(p)
149 CALL dgetrf(n, n, a, n, ipivot, info)
151 determinant = product(
diag)
153 IF (ipivot(i) /= i) p = p + 1
159 det_a = determinant*(-2*mod(p, 2) + 1.0_dp)
173 REAL(kind=
dp),
INTENT(IN) :: alpha
175 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: beta
176 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_b
178 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_scale_and_add'
180 INTEGER :: handle, size_a, size_b
181 REAL(kind=
dp) :: my_beta
182 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
183 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp, b_sp
185 CALL timeset(routinen, handle)
188 IF (
PRESENT(matrix_b)) my_beta = 1.0_dp
189 IF (
PRESENT(beta)) my_beta = beta
192 IF (
PRESENT(beta))
THEN
193 cpassert(
PRESENT(matrix_b))
194 IF (
ASSOCIATED(matrix_a%local_data, matrix_b%local_data))
THEN
195 cpwarn(
"Bad use of routine. Call cp_fm_scale instead")
197 CALL timestop(handle)
202 a => matrix_a%local_data
203 a_sp => matrix_a%local_data_sp
205 IF (matrix_a%use_sp)
THEN
206 size_a =
SIZE(a_sp, 1)*
SIZE(a_sp, 2)
208 size_a =
SIZE(a, 1)*
SIZE(a, 2)
211 IF (alpha /= 1.0_dp)
THEN
212 IF (matrix_a%use_sp)
THEN
213 CALL sscal(size_a, real(alpha,
sp), a_sp, 1)
215 CALL dscal(size_a, alpha, a, 1)
218 IF (my_beta /= 0.0_dp)
THEN
219 IF (matrix_a%matrix_struct%context /= matrix_b%matrix_struct%context) &
220 cpabort(
"Matrices must be in the same blacs context")
223 matrix_b%matrix_struct))
THEN
225 b => matrix_b%local_data
226 b_sp => matrix_b%local_data_sp
227 IF (matrix_b%use_sp)
THEN
228 size_b =
SIZE(b_sp, 1)*
SIZE(b_sp, 2)
230 size_b =
SIZE(b, 1)*
SIZE(b, 2)
232 IF (size_a /= size_b) &
233 cpabort(
"Matrices must have same local sizes")
235 IF (matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
236 CALL saxpy(size_a, real(my_beta,
sp), b_sp, 1, a_sp, 1)
237 ELSEIF (matrix_a%use_sp .AND. .NOT. matrix_b%use_sp)
THEN
238 CALL saxpy(size_a, real(my_beta,
sp), real(b,
sp), 1, a_sp, 1)
239 ELSEIF (.NOT. matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
240 CALL daxpy(size_a, my_beta, real(b_sp,
dp), 1, a, 1)
242 CALL daxpy(size_a, my_beta, b, 1, a, 1)
247 cpabort(
"to do (pdscal,pdcopy,pdaxpy)")
255 CALL timestop(handle)
276 REAL(kind=
dp),
INTENT(IN) :: alpha, beta
277 CHARACTER,
INTENT(IN) :: trans
278 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
280 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_geadd'
282 INTEGER :: nrow_global, ncol_global, handle
283 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: aa, bb
284#if defined(__parallel)
285 INTEGER,
DIMENSION(9) :: desca, descb
290 CALL timeset(routinen, handle)
292 nrow_global = matrix_a%matrix_struct%nrow_global
293 ncol_global = matrix_a%matrix_struct%ncol_global
294 cpassert(nrow_global == matrix_b%matrix_struct%nrow_global)
295 cpassert(ncol_global == matrix_b%matrix_struct%ncol_global)
297 aa => matrix_a%local_data
298 bb => matrix_b%local_data
300#if defined(__parallel)
301 desca = matrix_a%matrix_struct%descriptor
302 descb = matrix_b%matrix_struct%descriptor
303 CALL pdgeadd(trans, &
315 CALL mkl_domatadd(
'C', trans,
'N', nrow_global, ncol_global, &
316 alpha, aa, nrow_global, beta, bb, nrow_global, bb, nrow_global)
322 DO jj = 1, ncol_global
323 DO ii = 1, nrow_global
324 bb(ii, jj) = beta*bb(ii, jj) + alpha*aa(jj, ii)
328 DO jj = 1, ncol_global
329 DO ii = 1, nrow_global
330 bb(ii, jj) = beta*bb(ii, jj) + alpha*aa(ii, jj)
336 CALL timestop(handle)
352 TYPE(
cp_fm_type),
INTENT(IN) :: msource, mtarget
353 INTEGER,
INTENT(IN) :: ncol
354 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: alpha
355 INTEGER,
INTENT(IN),
OPTIONAL :: source_start, target_start
357 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_add_columns'
359 INTEGER :: handle, n, ss, ts, i
360 REAL(kind=
dp) :: fscale
361 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
362#if defined(__parallel)
363 INTEGER,
DIMENSION(9) :: desca, descb
366 CALL timeset(routinen, handle)
371 IF (
PRESENT(source_start)) ss = source_start
372 IF (
PRESENT(target_start)) ts = target_start
375 IF (
PRESENT(alpha)) fscale = alpha
377 n = msource%matrix_struct%nrow_global
379 a => msource%local_data
380 b => mtarget%local_data
382#if defined(__parallel)
384 desca(:) = msource%matrix_struct%descriptor(:)
385 descb(:) = mtarget%matrix_struct%descriptor(:)
386 CALL pdgeadd(
"N", n, ncol, fscale, a, 1, ss, desca, 1.0_dp, b, 1, ts, descb)
389 b(1:n, ts + i) = b(1:n, ts + i) + fscale*a(1:n, ss + i)
393 CALL timestop(handle)
414 SUBROUTINE cp_fm_lu_decompose(matrix_a, almost_determinant, correct_sign)
416 REAL(kind=
dp),
INTENT(OUT) :: almost_determinant
417 LOGICAL,
INTENT(IN),
OPTIONAL :: correct_sign
419 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_lu_decompose'
421 INTEGER :: handle, i, info, n
422 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
423 REAL(kind=
dp) :: determinant
424 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
425#if defined(__parallel)
426 INTEGER,
DIMENSION(9) :: desca
427 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
diag
432 CALL timeset(routinen, handle)
434 a => matrix_a%local_data
435 n = matrix_a%matrix_struct%nrow_global
436 ALLOCATE (ipivot(n + matrix_a%matrix_struct%nrow_block))
438#if defined(__parallel)
439 mark_used(correct_sign)
440 desca(:) = matrix_a%matrix_struct%descriptor(:)
441 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
448 determinant = determinant*
diag(i)
453 CALL dgetrf(n, n, a, lda, ipivot, info)
455 IF (correct_sign)
THEN
457 IF (ipivot(i) /= i)
THEN
458 determinant = -determinant*a(i, i)
460 determinant = determinant*a(i, i)
465 determinant = determinant*a(i, i)
472 almost_determinant = determinant
473 CALL timestop(handle)
474 END SUBROUTINE cp_fm_lu_decompose
499 SUBROUTINE cp_fm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, &
500 matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, &
501 c_first_col, c_first_row)
503 CHARACTER(LEN=1),
INTENT(IN) :: transa, transb
504 INTEGER,
INTENT(IN) :: m, n, k
505 REAL(kind=
dp),
INTENT(IN) :: alpha
506 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
507 REAL(kind=
dp),
INTENT(IN) :: beta
509 INTEGER,
INTENT(IN),
OPTIONAL :: a_first_col, a_first_row, &
510 b_first_col, b_first_row, &
511 c_first_col, c_first_row
513 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_gemm'
515 INTEGER :: handle, i_a, i_b, i_c, j_a, &
517 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b, c
518 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp, b_sp, c_sp
519#if defined(__parallel)
520 INTEGER,
DIMENSION(9) :: desca, descb, descc
522 INTEGER :: lda, ldb, ldc
525 CALL timeset(routinen, handle)
530 a => matrix_a%local_data
531 b => matrix_b%local_data
532 c => matrix_c%local_data
534 a_sp => matrix_a%local_data_sp
535 b_sp => matrix_b%local_data_sp
536 c_sp => matrix_c%local_data_sp
539 IF (
PRESENT(a_first_row)) i_a = a_first_row
542 IF (
PRESENT(a_first_col)) j_a = a_first_col
545 IF (
PRESENT(b_first_row)) i_b = b_first_row
548 IF (
PRESENT(b_first_col)) j_b = b_first_col
551 IF (
PRESENT(c_first_row)) i_c = c_first_row
554 IF (
PRESENT(c_first_col)) j_c = c_first_col
556#if defined(__parallel)
558 desca(:) = matrix_a%matrix_struct%descriptor(:)
559 descb(:) = matrix_b%matrix_struct%descriptor(:)
560 descc(:) = matrix_c%matrix_struct%descriptor(:)
562 IF (matrix_a%use_sp .AND. matrix_b%use_sp .AND. matrix_c%use_sp)
THEN
564 CALL psgemm(transa, transb, m, n, k, real(alpha,
sp), a_sp(1, 1), i_a, j_a, desca, b_sp(1, 1), i_b, j_b, &
565 descb, real(beta,
sp), c_sp(1, 1), i_c, j_c, descc)
567 ELSEIF ((.NOT. matrix_a%use_sp) .AND. (.NOT. matrix_b%use_sp) .AND. (.NOT. matrix_c%use_sp))
THEN
569 CALL pdgemm(transa, transb, m, n, k, alpha, a, i_a, j_a, desca, b, i_b, j_b, &
570 descb, beta, c, i_c, j_c, descc)
573 cpabort(
"Mixed precision gemm NYI")
577 IF (matrix_a%use_sp .AND. matrix_b%use_sp .AND. matrix_c%use_sp)
THEN
583 CALL sgemm(transa, transb, m, n, k, real(alpha,
sp), a_sp(i_a, j_a), lda, b_sp(i_b, j_b), ldb, &
584 REAL(beta,
sp), c_sp(i_c, j_c), ldc)
586 ELSEIF ((.NOT. matrix_a%use_sp) .AND. (.NOT. matrix_b%use_sp) .AND. (.NOT. matrix_c%use_sp))
THEN
592 CALL dgemm(transa, transb, m, n, k, alpha, a(i_a, j_a), lda, b(i_b, j_b), ldb, beta, c(i_c, j_c), ldc)
595 cpabort(
"Mixed precision gemm NYI")
599 CALL timestop(handle)
624 SUBROUTINE cp_fm_symm(side, uplo, m, n, alpha, matrix_a, matrix_b, beta, matrix_c)
626 CHARACTER(LEN=1),
INTENT(IN) :: side, uplo
627 INTEGER,
INTENT(IN) :: m, n
628 REAL(kind=
dp),
INTENT(IN) :: alpha
629 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
630 REAL(kind=
dp),
INTENT(IN) :: beta
633 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_symm'
636 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b, c
637#if defined(__parallel)
638 INTEGER,
DIMENSION(9) :: desca, descb, descc
640 INTEGER :: lda, ldb, ldc
643 CALL timeset(routinen, handle)
645 a => matrix_a%local_data
646 b => matrix_b%local_data
647 c => matrix_c%local_data
649#if defined(__parallel)
651 desca(:) = matrix_a%matrix_struct%descriptor(:)
652 descb(:) = matrix_b%matrix_struct%descriptor(:)
653 descc(:) = matrix_c%matrix_struct%descriptor(:)
655 CALL pdsymm(side, uplo, m, n, alpha, a(1, 1), 1, 1, desca, b(1, 1), 1, 1, descb, beta, c(1, 1), 1, 1, descc)
659 lda = matrix_a%matrix_struct%local_leading_dimension
660 ldb = matrix_b%matrix_struct%local_leading_dimension
661 ldc = matrix_c%matrix_struct%local_leading_dimension
663 CALL dsymm(side, uplo, m, n, alpha, a(1, 1), lda, b(1, 1), ldb, beta, c(1, 1), ldc)
666 CALL timestop(handle)
679 REAL(kind=
dp) :: norm
681 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_frobenius_norm'
683 INTEGER :: handle, size_a
684 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
685 REAL(kind=
dp),
EXTERNAL :: ddot
686#if defined(__parallel)
690 CALL timeset(routinen, handle)
693 a => matrix_a%local_data
694 size_a =
SIZE(a, 1)*
SIZE(a, 2)
695 norm = ddot(size_a, a(1, 1), 1, a(1, 1), 1)
696#if defined(__parallel)
697 group = matrix_a%matrix_struct%para_env
702 CALL timestop(handle)
721 SUBROUTINE cp_fm_syrk(uplo, trans, k, alpha, matrix_a, ia, ja, beta, matrix_c)
722 CHARACTER(LEN=1),
INTENT(IN) :: uplo, trans
723 INTEGER,
INTENT(IN) :: k
724 REAL(kind=
dp),
INTENT(IN) :: alpha
726 INTEGER,
INTENT(IN) :: ia, ja
727 REAL(kind=
dp),
INTENT(IN) :: beta
730 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_syrk'
733 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, c
734#if defined(__parallel)
735 INTEGER,
DIMENSION(9) :: desca, descc
739#if defined (__HAS_IEEE_EXCEPTIONS)
740 LOGICAL,
DIMENSION(5) :: halt
743 CALL timeset(routinen, handle)
745 n = matrix_c%matrix_struct%nrow_global
747 a => matrix_a%local_data
748 c => matrix_c%local_data
750#if defined (__HAS_IEEE_EXCEPTIONS)
751 CALL ieee_get_halting_mode(ieee_all, halt)
752 CALL ieee_set_halting_mode(ieee_all, .false.)
754#if defined(__parallel)
755 desca(:) = matrix_a%matrix_struct%descriptor(:)
756 descc(:) = matrix_c%matrix_struct%descriptor(:)
758 CALL pdsyrk(uplo, trans, n, k, alpha, a(1, 1), ia, ja, desca, beta, c(1, 1), 1, 1, descc)
763 CALL dsyrk(uplo, trans, n, k, alpha, a(ia, ja), lda, beta, c(1, 1), ldc)
765#if defined (__HAS_IEEE_EXCEPTIONS)
766 CALL ieee_set_halting_mode(ieee_all, halt)
768 CALL timestop(handle)
782 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b, matrix_c
784 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_schur_product'
786 INTEGER :: handle, icol_local, irow_local, mypcol, &
787 myprow, ncol_local, &
789 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b, c
792 CALL timeset(routinen, handle)
794 context => matrix_a%matrix_struct%context
795 myprow = context%mepos(1)
796 mypcol = context%mepos(2)
798 a => matrix_a%local_data
799 b => matrix_b%local_data
800 c => matrix_c%local_data
802 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
803 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
805 DO icol_local = 1, ncol_local
806 DO irow_local = 1, nrow_local
807 c(irow_local, icol_local) = a(irow_local, icol_local)*b(irow_local, icol_local)
811 CALL timestop(handle)
828 SUBROUTINE cp_fm_trace_a0b0t0(matrix_a, matrix_b, trace)
830 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
831 REAL(KIND=
dp),
INTENT(OUT) :: trace
833 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a0b0t0'
835 INTEGER :: handle, mypcol, myprow, ncol_local, &
837 REAL(KIND=
dp),
DIMENSION(:, :),
POINTER :: a, b
838 REAL(KIND=
sp),
DIMENSION(:, :),
POINTER :: a_sp, b_sp
842 CALL timeset(routinen, handle)
844 context => matrix_a%matrix_struct%context
845 myprow = context%mepos(1)
846 mypcol = context%mepos(2)
848 group = matrix_a%matrix_struct%para_env
850 a => matrix_a%local_data
851 b => matrix_b%local_data
853 a_sp => matrix_a%local_data_sp
854 b_sp => matrix_b%local_data_sp
856 nrow_local = min(matrix_a%matrix_struct%nrow_locals(myprow), matrix_b%matrix_struct%nrow_locals(myprow))
857 ncol_local = min(matrix_a%matrix_struct%ncol_locals(mypcol), matrix_b%matrix_struct%ncol_locals(mypcol))
860 IF (matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
861 trace =
accurate_sum(real(a_sp(1:nrow_local, 1:ncol_local)* &
862 b_sp(1:nrow_local, 1:ncol_local),
dp))
863 ELSEIF (matrix_a%use_sp .AND. .NOT. matrix_b%use_sp)
THEN
864 trace =
accurate_sum(real(a_sp(1:nrow_local, 1:ncol_local),
dp)* &
865 b(1:nrow_local, 1:ncol_local))
866 ELSEIF (.NOT. matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
868 REAL(b_sp(1:nrow_local, 1:ncol_local), dp))
871 b(1:nrow_local, 1:ncol_local))
874 CALL group%sum(trace)
876 CALL timestop(handle)
878 END SUBROUTINE cp_fm_trace_a0b0t0
899 SUBROUTINE cp_fm_trace_a1b0t1_a (matrix_a, matrix_b, trace)
900 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
902 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
904 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b0t1_a'
906 INTEGER :: handle, imatrix, n_matrices, &
907 ncols_local, nrows_local
908 LOGICAL :: use_sp_a, use_sp_b
909 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
910 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
913 CALL timeset(routinen, handle)
915 n_matrices =
SIZE(trace)
916 cpassert(
SIZE(matrix_a) == n_matrices)
918 CALL cp_fm_get_info(matrix_b, nrow_local=nrows_local, ncol_local=ncols_local)
919 use_sp_b = matrix_b%use_sp
922 ldata_b_sp => matrix_b%local_data_sp(1:nrows_local, 1:ncols_local)
924 ldata_b => matrix_b%local_data(1:nrows_local, 1:ncols_local)
932 DO imatrix = 1, n_matrices
934 use_sp_a = matrix_a(imatrix) %use_sp
937 IF (use_sp_a .AND. use_sp_b)
THEN
938 ldata_a_sp => matrix_a(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
940 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
941 ldata_a => matrix_a(imatrix) %local_data(1:nrows_local, 1:ncols_local)
944 cpabort(
"Matrices A and B are of different types")
949 group = matrix_b%matrix_struct%para_env
950 CALL group%sum(trace)
952 CALL timestop(handle)
953 END SUBROUTINE cp_fm_trace_a1b0t1_a
954 SUBROUTINE cp_fm_trace_a1b0t1_p (matrix_a, matrix_b, trace)
955 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
957 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
959 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b0t1_p'
961 INTEGER :: handle, imatrix, n_matrices, &
962 ncols_local, nrows_local
963 LOGICAL :: use_sp_a, use_sp_b
964 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
965 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
968 CALL timeset(routinen, handle)
970 n_matrices =
SIZE(trace)
971 cpassert(
SIZE(matrix_a) == n_matrices)
973 CALL cp_fm_get_info(matrix_b, nrow_local=nrows_local, ncol_local=ncols_local)
974 use_sp_b = matrix_b%use_sp
977 ldata_b_sp => matrix_b%local_data_sp(1:nrows_local, 1:ncols_local)
979 ldata_b => matrix_b%local_data(1:nrows_local, 1:ncols_local)
987 DO imatrix = 1, n_matrices
989 use_sp_a = matrix_a(imatrix) %matrix%use_sp
992 IF (use_sp_a .AND. use_sp_b)
THEN
993 ldata_a_sp => matrix_a(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
995 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
996 ldata_a => matrix_a(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
999 cpabort(
"Matrices A and B are of different types")
1004 group = matrix_b%matrix_struct%para_env
1005 CALL group%sum(trace)
1007 CALL timestop(handle)
1008 END SUBROUTINE cp_fm_trace_a1b0t1_p
1028 SUBROUTINE cp_fm_trace_a1b1t1_aa (matrix_a, matrix_b, trace, accurate)
1029 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1030 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1031 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1032 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1034 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_aa'
1036 INTEGER :: handle, imatrix, n_matrices, &
1037 ncols_local, nrows_local
1038 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1039 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1040 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1043 CALL timeset(routinen, handle)
1045 n_matrices =
SIZE(trace)
1046 cpassert(
SIZE(matrix_a) == n_matrices)
1047 cpassert(
SIZE(matrix_b) == n_matrices)
1049 use_accurate_sum = .true.
1050 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1056 DO imatrix = 1, n_matrices
1057 CALL cp_fm_get_info(matrix_a(imatrix) , nrow_local=nrows_local, ncol_local=ncols_local)
1059 use_sp_a = matrix_a(imatrix) %use_sp
1060 use_sp_b = matrix_b(imatrix) %use_sp
1063 IF (use_sp_a .AND. use_sp_b)
THEN
1064 ldata_a_sp => matrix_a(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1065 ldata_b_sp => matrix_b(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1066 IF (use_accurate_sum)
THEN
1069 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1071 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1072 ldata_a => matrix_a(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1073 ldata_b => matrix_b(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1074 IF (use_accurate_sum)
THEN
1077 trace(imatrix) = sum(ldata_a*ldata_b)
1080 cpabort(
"Matrices A and B are of different types")
1085 group = matrix_a(1) %matrix_struct%para_env
1086 CALL group%sum(trace)
1088 CALL timestop(handle)
1089 END SUBROUTINE cp_fm_trace_a1b1t1_aa
1090 SUBROUTINE cp_fm_trace_a1b1t1_ap (matrix_a, matrix_b, trace, accurate)
1091 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1092 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1093 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1094 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1096 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_ap'
1098 INTEGER :: handle, imatrix, n_matrices, &
1099 ncols_local, nrows_local
1100 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1101 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1102 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1105 CALL timeset(routinen, handle)
1107 n_matrices =
SIZE(trace)
1108 cpassert(
SIZE(matrix_a) == n_matrices)
1109 cpassert(
SIZE(matrix_b) == n_matrices)
1111 use_accurate_sum = .true.
1112 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1118 DO imatrix = 1, n_matrices
1119 CALL cp_fm_get_info(matrix_a(imatrix) , nrow_local=nrows_local, ncol_local=ncols_local)
1121 use_sp_a = matrix_a(imatrix) %use_sp
1122 use_sp_b = matrix_b(imatrix) %matrix%use_sp
1125 IF (use_sp_a .AND. use_sp_b)
THEN
1126 ldata_a_sp => matrix_a(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1127 ldata_b_sp => matrix_b(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1128 IF (use_accurate_sum)
THEN
1131 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1133 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1134 ldata_a => matrix_a(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1135 ldata_b => matrix_b(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1136 IF (use_accurate_sum)
THEN
1139 trace(imatrix) = sum(ldata_a*ldata_b)
1142 cpabort(
"Matrices A and B are of different types")
1147 group = matrix_a(1) %matrix_struct%para_env
1148 CALL group%sum(trace)
1150 CALL timestop(handle)
1151 END SUBROUTINE cp_fm_trace_a1b1t1_ap
1152 SUBROUTINE cp_fm_trace_a1b1t1_pa (matrix_a, matrix_b, trace, accurate)
1153 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1154 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1155 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1156 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1158 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_pa'
1160 INTEGER :: handle, imatrix, n_matrices, &
1161 ncols_local, nrows_local
1162 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1163 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1164 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1167 CALL timeset(routinen, handle)
1169 n_matrices =
SIZE(trace)
1170 cpassert(
SIZE(matrix_a) == n_matrices)
1171 cpassert(
SIZE(matrix_b) == n_matrices)
1173 use_accurate_sum = .true.
1174 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1180 DO imatrix = 1, n_matrices
1181 CALL cp_fm_get_info(matrix_a(imatrix) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1183 use_sp_a = matrix_a(imatrix) %matrix%use_sp
1184 use_sp_b = matrix_b(imatrix) %use_sp
1187 IF (use_sp_a .AND. use_sp_b)
THEN
1188 ldata_a_sp => matrix_a(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1189 ldata_b_sp => matrix_b(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1190 IF (use_accurate_sum)
THEN
1193 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1195 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1196 ldata_a => matrix_a(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1197 ldata_b => matrix_b(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1198 IF (use_accurate_sum)
THEN
1201 trace(imatrix) = sum(ldata_a*ldata_b)
1204 cpabort(
"Matrices A and B are of different types")
1209 group = matrix_a(1) %matrix%matrix_struct%para_env
1210 CALL group%sum(trace)
1212 CALL timestop(handle)
1213 END SUBROUTINE cp_fm_trace_a1b1t1_pa
1214 SUBROUTINE cp_fm_trace_a1b1t1_pp (matrix_a, matrix_b, trace, accurate)
1215 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1216 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1217 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1218 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1220 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_pp'
1222 INTEGER :: handle, imatrix, n_matrices, &
1223 ncols_local, nrows_local
1224 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1225 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1226 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1229 CALL timeset(routinen, handle)
1231 n_matrices =
SIZE(trace)
1232 cpassert(
SIZE(matrix_a) == n_matrices)
1233 cpassert(
SIZE(matrix_b) == n_matrices)
1235 use_accurate_sum = .true.
1236 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1242 DO imatrix = 1, n_matrices
1243 CALL cp_fm_get_info(matrix_a(imatrix) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1245 use_sp_a = matrix_a(imatrix) %matrix%use_sp
1246 use_sp_b = matrix_b(imatrix) %matrix%use_sp
1249 IF (use_sp_a .AND. use_sp_b)
THEN
1250 ldata_a_sp => matrix_a(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1251 ldata_b_sp => matrix_b(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1252 IF (use_accurate_sum)
THEN
1255 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1257 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1258 ldata_a => matrix_a(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1259 ldata_b => matrix_b(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1260 IF (use_accurate_sum)
THEN
1263 trace(imatrix) = sum(ldata_a*ldata_b)
1266 cpabort(
"Matrices A and B are of different types")
1271 group = matrix_a(1) %matrix%matrix_struct%para_env
1272 CALL group%sum(trace)
1274 CALL timestop(handle)
1275 END SUBROUTINE cp_fm_trace_a1b1t1_pp
1284 SUBROUTINE cp_fm_contracted_trace_a2b2t2_aa (matrix_a, matrix_b, trace, accurate)
1285 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1286 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1287 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1288 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1290 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_aa'
1292 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1294 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1295 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1297 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1298 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1301 CALL timeset(routinen, handle)
1303 nz =
SIZE(matrix_a, 1)
1304 cpassert(
SIZE(matrix_b, 1) == nz)
1306 na =
SIZE(matrix_a, 2)
1307 nb =
SIZE(matrix_b, 2)
1308 cpassert(
SIZE(trace, 1) == na)
1309 cpassert(
SIZE(trace, 2) == nb)
1311 use_accurate_sum = .true.
1312 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1317 na8 = int(na, kind=
int_8)
1323 DO itrace = 1, ntraces
1324 ib8 = (itrace - 1)/na8
1325 ia = int(itrace - ib8*na8)
1330 CALL cp_fm_get_info(matrix_a(iz, ia) , nrow_local=nrows_local, ncol_local=ncols_local)
1331 use_sp_a = matrix_a(iz, ia) %use_sp
1332 use_sp_b = matrix_b(iz, ib) %use_sp
1335 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1336 ldata_a => matrix_a(iz, ia) %local_data(1:nrows_local, 1:ncols_local)
1337 ldata_b => matrix_b(iz, ib) %local_data(1:nrows_local, 1:ncols_local)
1338 IF (use_accurate_sum)
THEN
1341 t = t + sum(ldata_a*ldata_b)
1343 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1344 ldata_a_sp => matrix_a(iz, ia) %local_data_sp(1:nrows_local, 1:ncols_local)
1345 ldata_b_sp => matrix_b(iz, ib) %local_data_sp(1:nrows_local, 1:ncols_local)
1346 IF (use_accurate_sum)
THEN
1349 t = t + sum(ldata_a_sp*ldata_b_sp)
1352 cpabort(
"Matrices A and B are of different types")
1359 group = matrix_a(1, 1) %matrix_struct%para_env
1360 CALL group%sum(trace)
1362 CALL timestop(handle)
1363 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_aa
1364 SUBROUTINE cp_fm_contracted_trace_a2b2t2_ap (matrix_a, matrix_b, trace, accurate)
1365 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1366 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1367 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1368 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1370 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_ap'
1372 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1374 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1375 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1377 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1378 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1381 CALL timeset(routinen, handle)
1383 nz =
SIZE(matrix_a, 1)
1384 cpassert(
SIZE(matrix_b, 1) == nz)
1386 na =
SIZE(matrix_a, 2)
1387 nb =
SIZE(matrix_b, 2)
1388 cpassert(
SIZE(trace, 1) == na)
1389 cpassert(
SIZE(trace, 2) == nb)
1391 use_accurate_sum = .true.
1392 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1397 na8 = int(na, kind=
int_8)
1403 DO itrace = 1, ntraces
1404 ib8 = (itrace - 1)/na8
1405 ia = int(itrace - ib8*na8)
1410 CALL cp_fm_get_info(matrix_a(iz, ia) , nrow_local=nrows_local, ncol_local=ncols_local)
1411 use_sp_a = matrix_a(iz, ia) %use_sp
1412 use_sp_b = matrix_b(iz, ib) %matrix%use_sp
1415 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1416 ldata_a => matrix_a(iz, ia) %local_data(1:nrows_local, 1:ncols_local)
1417 ldata_b => matrix_b(iz, ib) %matrix%local_data(1:nrows_local, 1:ncols_local)
1418 IF (use_accurate_sum)
THEN
1421 t = t + sum(ldata_a*ldata_b)
1423 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1424 ldata_a_sp => matrix_a(iz, ia) %local_data_sp(1:nrows_local, 1:ncols_local)
1425 ldata_b_sp => matrix_b(iz, ib) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1426 IF (use_accurate_sum)
THEN
1429 t = t + sum(ldata_a_sp*ldata_b_sp)
1432 cpabort(
"Matrices A and B are of different types")
1439 group = matrix_a(1, 1) %matrix_struct%para_env
1440 CALL group%sum(trace)
1442 CALL timestop(handle)
1443 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_ap
1444 SUBROUTINE cp_fm_contracted_trace_a2b2t2_pa (matrix_a, matrix_b, trace, accurate)
1445 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1446 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1447 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1448 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1450 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_pa'
1452 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1454 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1455 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1457 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1458 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1461 CALL timeset(routinen, handle)
1463 nz =
SIZE(matrix_a, 1)
1464 cpassert(
SIZE(matrix_b, 1) == nz)
1466 na =
SIZE(matrix_a, 2)
1467 nb =
SIZE(matrix_b, 2)
1468 cpassert(
SIZE(trace, 1) == na)
1469 cpassert(
SIZE(trace, 2) == nb)
1471 use_accurate_sum = .true.
1472 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1477 na8 = int(na, kind=
int_8)
1483 DO itrace = 1, ntraces
1484 ib8 = (itrace - 1)/na8
1485 ia = int(itrace - ib8*na8)
1490 CALL cp_fm_get_info(matrix_a(iz, ia) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1491 use_sp_a = matrix_a(iz, ia) %matrix%use_sp
1492 use_sp_b = matrix_b(iz, ib) %use_sp
1495 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1496 ldata_a => matrix_a(iz, ia) %matrix%local_data(1:nrows_local, 1:ncols_local)
1497 ldata_b => matrix_b(iz, ib) %local_data(1:nrows_local, 1:ncols_local)
1498 IF (use_accurate_sum)
THEN
1501 t = t + sum(ldata_a*ldata_b)
1503 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1504 ldata_a_sp => matrix_a(iz, ia) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1505 ldata_b_sp => matrix_b(iz, ib) %local_data_sp(1:nrows_local, 1:ncols_local)
1506 IF (use_accurate_sum)
THEN
1509 t = t + sum(ldata_a_sp*ldata_b_sp)
1512 cpabort(
"Matrices A and B are of different types")
1519 group = matrix_a(1, 1) %matrix%matrix_struct%para_env
1520 CALL group%sum(trace)
1522 CALL timestop(handle)
1523 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_pa
1524 SUBROUTINE cp_fm_contracted_trace_a2b2t2_pp (matrix_a, matrix_b, trace, accurate)
1525 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1526 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1527 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1528 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1530 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_pp'
1532 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1534 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1535 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1537 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1538 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1541 CALL timeset(routinen, handle)
1543 nz =
SIZE(matrix_a, 1)
1544 cpassert(
SIZE(matrix_b, 1) == nz)
1546 na =
SIZE(matrix_a, 2)
1547 nb =
SIZE(matrix_b, 2)
1548 cpassert(
SIZE(trace, 1) == na)
1549 cpassert(
SIZE(trace, 2) == nb)
1551 use_accurate_sum = .true.
1552 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1557 na8 = int(na, kind=
int_8)
1563 DO itrace = 1, ntraces
1564 ib8 = (itrace - 1)/na8
1565 ia = int(itrace - ib8*na8)
1570 CALL cp_fm_get_info(matrix_a(iz, ia) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1571 use_sp_a = matrix_a(iz, ia) %matrix%use_sp
1572 use_sp_b = matrix_b(iz, ib) %matrix%use_sp
1575 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1576 ldata_a => matrix_a(iz, ia) %matrix%local_data(1:nrows_local, 1:ncols_local)
1577 ldata_b => matrix_b(iz, ib) %matrix%local_data(1:nrows_local, 1:ncols_local)
1578 IF (use_accurate_sum)
THEN
1581 t = t + sum(ldata_a*ldata_b)
1583 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1584 ldata_a_sp => matrix_a(iz, ia) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1585 ldata_b_sp => matrix_b(iz, ib) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1586 IF (use_accurate_sum)
THEN
1589 t = t + sum(ldata_a_sp*ldata_b_sp)
1592 cpabort(
"Matrices A and B are of different types")
1599 group = matrix_a(1, 1) %matrix%matrix_struct%para_env
1600 CALL group%sum(trace)
1602 CALL timestop(handle)
1603 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_pp
1639 transpose_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, &
1641 TYPE(
cp_fm_type),
INTENT(IN) :: triangular_matrix, matrix_b
1642 CHARACTER,
INTENT(IN),
OPTIONAL :: side
1643 LOGICAL,
INTENT(IN),
OPTIONAL :: transpose_tr, invert_tr
1644 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo_tr
1645 LOGICAL,
INTENT(IN),
OPTIONAL :: unit_diag_tr
1646 INTEGER,
INTENT(IN),
OPTIONAL :: n_rows, n_cols
1647 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: alpha
1649 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_triangular_multiply'
1651 CHARACTER :: side_char, transa, unit_diag, uplo
1652 INTEGER :: handle, mdim, m, n
1656 CALL timeset(routinen, handle)
1664 IF (
PRESENT(side)) side_char = side
1665 mdim = merge(1, 2,
'L' == side_char)
1666 IF (
PRESENT(invert_tr)) invert = invert_tr
1667 IF (
PRESENT(uplo_tr)) uplo = uplo_tr
1668 IF (
PRESENT(unit_diag_tr))
THEN
1669 IF (unit_diag_tr)
THEN
1675 IF (
PRESENT(transpose_tr))
THEN
1676 IF (transpose_tr)
THEN
1682 IF (
PRESENT(alpha)) al = alpha
1683 IF (
PRESENT(n_rows)) m = n_rows
1684 IF (
PRESENT(n_cols)) n = n_cols
1688#if defined(__parallel)
1689 CALL pdtrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1690 triangular_matrix%local_data(1, 1), 1, 1, &
1691 triangular_matrix%matrix_struct%descriptor, &
1692 matrix_b%local_data(1, 1), 1, 1, &
1693 matrix_b%matrix_struct%descriptor(1))
1695 CALL dtrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1696 triangular_matrix%local_data(1, 1), &
1697 SIZE(triangular_matrix%local_data, mdim), &
1698 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1703#if defined(__parallel)
1704 CALL pdtrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1705 triangular_matrix%local_data(1, 1), 1, 1, &
1706 triangular_matrix%matrix_struct%descriptor, &
1707 matrix_b%local_data(1, 1), 1, 1, &
1708 matrix_b%matrix_struct%descriptor(1))
1710 CALL dtrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1711 triangular_matrix%local_data(1, 1), &
1712 SIZE(triangular_matrix%local_data, mdim), &
1713 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1718 CALL timestop(handle)
1730 REAL(kind=
dp),
INTENT(IN) :: alpha
1733 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_scale'
1735 INTEGER :: handle, size_a
1736 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1738 CALL timeset(routinen, handle)
1742 a => matrix_a%local_data
1743 size_a =
SIZE(a, 1)*
SIZE(a, 2)
1745 CALL dscal(size_a, alpha, a, 1)
1747 CALL timestop(handle)
1760 TYPE(
cp_fm_type),
INTENT(IN) :: matrix, matrixt
1762 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_transpose'
1764 INTEGER :: handle, ncol_global, &
1765 nrow_global, ncol_globalt, nrow_globalt
1766 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, c
1767#if defined(__parallel)
1768 INTEGER,
DIMENSION(9) :: desca, descc
1769#elif !defined(__MKL)
1773 nrow_global = matrix%matrix_struct%nrow_global
1774 ncol_global = matrix%matrix_struct%ncol_global
1775 nrow_globalt = matrixt%matrix_struct%nrow_global
1776 ncol_globalt = matrixt%matrix_struct%ncol_global
1777 cpassert(nrow_global == ncol_globalt)
1778 cpassert(nrow_globalt == ncol_global)
1780 CALL timeset(routinen, handle)
1782 a => matrix%local_data
1783 c => matrixt%local_data
1785#if defined(__parallel)
1786 desca(:) = matrix%matrix_struct%descriptor(:)
1787 descc(:) = matrixt%matrix_struct%descriptor(:)
1788 CALL pdtran(ncol_global, nrow_global, 1.0_dp, a(1, 1), 1, 1, desca, 0.0_dp, c(1, 1), 1, 1, descc)
1790 CALL mkl_domatcopy(
'C',
'T', nrow_global, ncol_global, 1.0_dp, a(1, 1), nrow_global, c(1, 1), ncol_global)
1792 DO j = 1, ncol_global
1793 DO i = 1, nrow_global
1798 CALL timestop(handle)
1814 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
1816 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_uplo_to_full'
1819 INTEGER :: handle, icol_global, irow_global, &
1820 mypcol, myprow, ncol_global, &
1822 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1823 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
1826#if defined(__parallel)
1827 INTEGER :: icol_local, irow_local, &
1828 ncol_block, ncol_local, &
1829 nrow_block, nrow_local
1830 INTEGER,
DIMENSION(9) :: desca, descc
1831 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: c
1832 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: c_sp
1836 IF (
PRESENT(uplo)) myuplo = uplo
1838 nrow_global = matrix%matrix_struct%nrow_global
1839 ncol_global = matrix%matrix_struct%ncol_global
1840 cpassert(nrow_global == ncol_global)
1841 nrow_global = work%matrix_struct%nrow_global
1842 ncol_global = work%matrix_struct%ncol_global
1843 cpassert(nrow_global == ncol_global)
1844 cpassert(matrix%use_sp .EQV. work%use_sp)
1846 CALL timeset(routinen, handle)
1848 context => matrix%matrix_struct%context
1849 myprow = context%mepos(1)
1850 mypcol = context%mepos(2)
1852#if defined(__parallel)
1854 nrow_block = matrix%matrix_struct%nrow_block
1855 ncol_block = matrix%matrix_struct%ncol_block
1857 nrow_local = matrix%matrix_struct%nrow_locals(myprow)
1858 ncol_local = matrix%matrix_struct%ncol_locals(mypcol)
1860 a => work%local_data
1861 a_sp => work%local_data_sp
1862 desca(:) = work%matrix_struct%descriptor(:)
1863 c => matrix%local_data
1864 c_sp => matrix%local_data_sp
1865 descc(:) = matrix%matrix_struct%descriptor(:)
1867 DO icol_local = 1, ncol_local
1868 icol_global = matrix%matrix_struct%col_indices(icol_local)
1869 DO irow_local = 1, nrow_local
1870 irow_global = matrix%matrix_struct%row_indices(irow_local)
1871 IF (merge(irow_global > icol_global, irow_global < icol_global, (myuplo ==
"U") .OR. (myuplo ==
"u")))
THEN
1872 IF (matrix%use_sp)
THEN
1873 c_sp(irow_local, icol_local) = 0.0_sp
1875 c(irow_local, icol_local) = 0.0_dp
1877 ELSE IF (irow_global == icol_global)
THEN
1878 IF (matrix%use_sp)
THEN
1879 c_sp(irow_local, icol_local) = 0.5_sp*c_sp(irow_local, icol_local)
1881 c(irow_local, icol_local) = 0.5_dp*c(irow_local, icol_local)
1887 DO icol_local = 1, ncol_local
1888 DO irow_local = 1, nrow_local
1889 IF (matrix%use_sp)
THEN
1890 a_sp(irow_local, icol_local) = c_sp(irow_local, icol_local)
1892 a(irow_local, icol_local) = c(irow_local, icol_local)
1897 IF (matrix%use_sp)
THEN
1898 CALL pstran(nrow_global, ncol_global, 1.0_sp, a_sp(1, 1), 1, 1, desca, 1.0_sp, c_sp(1, 1), 1, 1, descc)
1900 CALL pdtran(nrow_global, ncol_global, 1.0_dp, a(1, 1), 1, 1, desca, 1.0_dp, c(1, 1), 1, 1, descc)
1905 a => matrix%local_data
1906 a_sp => matrix%local_data_sp
1908 IF ((myuplo ==
"U") .OR. (myuplo ==
"u"))
THEN
1909 DO irow_global = 1, nrow_global
1910 DO icol_global = irow_global + 1, ncol_global
1911 IF (matrix%use_sp)
THEN
1912 a_sp(icol_global, irow_global) = a_sp(irow_global, icol_global)
1914 a(icol_global, irow_global) = a(irow_global, icol_global)
1919 DO icol_global = 1, ncol_global
1920 DO irow_global = icol_global + 1, nrow_global
1921 IF (matrix%use_sp)
THEN
1922 a_sp(irow_global, icol_global) = a_sp(icol_global, irow_global)
1924 a(irow_global, icol_global) = a(icol_global, irow_global)
1931 CALL timestop(handle)
1949 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: scaling
1951 INTEGER :: k, mypcol, myprow, n, ncol_global, &
1953 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1954 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
1955#if defined(__parallel)
1956 INTEGER :: icol_global, icol_local, &
1957 ipcol, iprow, irow_local
1962 myprow = matrixa%matrix_struct%context%mepos(1)
1963 mypcol = matrixa%matrix_struct%context%mepos(2)
1964 nprow = matrixa%matrix_struct%context%num_pe(1)
1965 npcol = matrixa%matrix_struct%context%num_pe(2)
1967 ncol_global = matrixa%matrix_struct%ncol_global
1969 a => matrixa%local_data
1970 a_sp => matrixa%local_data_sp
1971 IF (matrixa%use_sp)
THEN
1976 k = min(
SIZE(scaling), ncol_global)
1978#if defined(__parallel)
1980 DO icol_global = 1, k
1981 CALL infog2l(1, icol_global, matrixa%matrix_struct%descriptor, &
1982 nprow, npcol, myprow, mypcol, &
1983 irow_local, icol_local, iprow, ipcol)
1984 IF ((ipcol == mypcol))
THEN
1985 IF (matrixa%use_sp)
THEN
1986 CALL sscal(n, real(scaling(icol_global),
sp), a_sp(:, icol_local), 1)
1988 CALL dscal(n, scaling(icol_global), a(:, icol_local), 1)
1994 IF (matrixa%use_sp)
THEN
1995 CALL sscal(n, real(scaling(i),
sp), a_sp(:, i), 1)
1997 CALL dscal(n, scaling(i), a(:, i), 1)
2012 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: scaling
2014 INTEGER :: n, m, nrow_global, nrow_local, ncol_local
2015 INTEGER,
DIMENSION(:),
POINTER :: row_indices
2016 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2017 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
2018#if defined(__parallel)
2019 INTEGER :: irow_global, icol, irow
2024 CALL cp_fm_get_info(matrixa, row_indices=row_indices, nrow_global=nrow_global, &
2025 nrow_local=nrow_local, ncol_local=ncol_local)
2026 cpassert(
SIZE(scaling) == nrow_global)
2028 a => matrixa%local_data
2029 a_sp => matrixa%local_data_sp
2030 IF (matrixa%use_sp)
THEN
2038#if defined(__parallel)
2039 DO icol = 1, ncol_local
2040 IF (matrixa%use_sp)
THEN
2041 DO irow = 1, nrow_local
2042 irow_global = row_indices(irow)
2043 a(irow, icol) = real(scaling(irow_global),
dp)*a(irow, icol)
2046 DO irow = 1, nrow_local
2047 irow_global = row_indices(irow)
2048 a(irow, icol) = scaling(irow_global)*a(irow, icol)
2053 IF (matrixa%use_sp)
THEN
2055 a_sp(1:n, j) = real(scaling(1:n),
sp)*a_sp(1:n, j)
2059 a(1:n, j) = scaling(1:n)*a(1:n, j)
2083 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_inverse
2084 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: det_a
2085 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_svd
2086 REAL(kind=
dp),
DIMENSION(:),
POINTER, &
2087 INTENT(INOUT),
OPTIONAL :: eigval
2090 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
2091 REAL(kind=
dp) :: determinant, my_eps_svd
2092 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2095#if defined(__parallel)
2096 TYPE(
cp_fm_type) :: u, vt, sigma, inv_sigma_ut
2098 INTEGER :: i, info, liwork, lwork, exponent_of_minus_one
2099 INTEGER,
DIMENSION(9) :: desca
2101 REAL(kind=
dp) :: alpha, beta
2102 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
diag
2103 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
2106 REAL(kind=
dp) :: eps1
2110 IF (
PRESENT(eps_svd)) my_eps_svd = eps_svd
2113 matrix_struct=matrix_a%matrix_struct, &
2117 a => matrix_lu%local_data
2118 n = matrix_lu%matrix_struct%nrow_global
2119 ALLOCATE (ipivot(n + matrix_a%matrix_struct%nrow_block))
2121#if defined(__parallel)
2122 IF (my_eps_svd == 0.0_dp)
THEN
2126 desca(:) = matrix_lu%matrix_struct%descriptor(:)
2127 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
2129 IF (
PRESENT(det_a) .OR.
PRESENT(eigval))
THEN
2135 exponent_of_minus_one = 0
2136 determinant = 1.0_dp
2138 determinant = determinant*
diag(i)
2139 IF (ipivot(i) /= i)
THEN
2140 exponent_of_minus_one = exponent_of_minus_one + 1
2143 IF (
PRESENT(eigval))
THEN
2144 cpassert(.NOT.
ASSOCIATED(eigval))
2145 ALLOCATE (eigval(n))
2150 group = matrix_lu%matrix_struct%para_env
2151 CALL group%sum(exponent_of_minus_one)
2153 determinant = determinant*(-1.0_dp)**exponent_of_minus_one
2160 CALL pdgetrs(
'N', n, n, matrix_lu%local_data, 1, 1, desca, ipivot, matrix_inverse%local_data, 1, 1, desca, info)
2164 matrix_struct=matrix_a%matrix_struct, &
2165 name=
"LEFT_SINGULAR_MATRIX")
2168 matrix_struct=matrix_a%matrix_struct, &
2169 name=
"RIGHT_SINGULAR_MATRIX")
2173 desca(:) = matrix_lu%matrix_struct%descriptor(:)
2177 CALL pdgesvd(
'V',
'V', n, n, matrix_lu%local_data, 1, 1, desca,
diag, u%local_data, &
2178 1, 1, desca, vt%local_data, 1, 1, desca, work, lwork, info)
2179 lwork = int(work(1))
2181 ALLOCATE (work(lwork))
2183 CALL pdgesvd(
'V',
'V', n, n, matrix_lu%local_data, 1, 1, desca,
diag, u%local_data, &
2184 1, 1, desca, vt%local_data, 1, 1, desca, work, lwork, info)
2187 IF (info /= 0 .AND. info /= n + 1) &
2188 cpabort(
"Singular value decomposition of matrix failed.")
2191 matrix_struct=matrix_a%matrix_struct, &
2192 name=
"SINGULAR_VALUE_MATRIX")
2194 determinant = 1.0_dp
2196 IF (
PRESENT(eigval))
THEN
2197 cpassert(.NOT.
ASSOCIATED(eigval))
2198 ALLOCATE (eigval(n))
2202 IF (
diag(i) < my_eps_svd)
THEN
2206 determinant = determinant*
diag(i)
2213 CALL cp_warn(__location__, &
2214 "Linear dependencies were detected in the SVD inversion of matrix "//trim(adjustl(matrix_a%name))// &
2215 ". At least one singular value has been quenched.")
2218 matrix_struct=matrix_a%matrix_struct, &
2219 name=
"SINGULAR_VALUE_MATRIX")
2221 CALL pdgemm(
'N',
'T', n, n, n, 1.0_dp, sigma%local_data, 1, 1, desca, &
2222 u%local_data, 1, 1, desca, 0.0_dp, inv_sigma_ut%local_data, 1, 1, desca)
2225 CALL pdgemm(
'T',
'N', n, n, n, 1.0_dp, vt%local_data, 1, 1, desca, &
2226 inv_sigma_ut%local_data, 1, 1, desca, 0.0_dp, matrix_inverse%local_data, 1, 1, desca)
2235 IF (my_eps_svd == 0.0_dp)
THEN
2237 CALL invert_matrix(matrix_a%local_data, matrix_inverse%local_data, &
2239 CALL cp_fm_lu_decompose(matrix_lu, determinant, correct_sign=sign)
2240 IF (
PRESENT(eigval)) &
2241 CALL cp_abort(__location__, &
2242 "NYI. Eigenvalues not available for return without SCALAPACK.")
2245 determinant, eigval)
2250 IF (
PRESENT(det_a)) det_a = determinant
2262 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo_tr
2264 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_triangular_invert'
2266 CHARACTER :: unit_diag, uplo
2267 INTEGER :: handle, info, ncol_global
2268 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2269#if defined(__parallel)
2270 INTEGER,
DIMENSION(9) :: desca
2273 CALL timeset(routinen, handle)
2277 IF (
PRESENT(uplo_tr)) uplo = uplo_tr
2279 ncol_global = matrix_a%matrix_struct%ncol_global
2281 a => matrix_a%local_data
2283#if defined(__parallel)
2284 desca(:) = matrix_a%matrix_struct%descriptor(:)
2286 CALL pdtrtri(uplo, unit_diag, ncol_global, a(1, 1), 1, 1, desca, info)
2289 CALL dtrtri(uplo, unit_diag, ncol_global, a(1, 1), ncol_global, info)
2292 CALL timestop(handle)
2308 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_r
2309 INTEGER,
INTENT(IN),
OPTIONAL :: nrow_fact, ncol_fact, &
2310 first_row, first_col
2311 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
2313 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_qr_factorization'
2316 INTEGER :: handle, i, icol, info, irow, &
2317 j, lda, lwork, ncol, &
2319 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tau, work
2320 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: r_mat
2321 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2322#if defined(__parallel)
2323 INTEGER,
DIMENSION(9) :: desca
2326 CALL timeset(routinen, handle)
2329 IF (
PRESENT(uplo)) myuplo = uplo
2331 ncol = matrix_a%matrix_struct%ncol_global
2332 nrow = matrix_a%matrix_struct%nrow_global
2335 a => matrix_a%local_data
2337 IF (
PRESENT(nrow_fact)) nrow = nrow_fact
2338 IF (
PRESENT(ncol_fact)) ncol = ncol_fact
2340 IF (
PRESENT(first_row)) irow = first_row
2342 IF (
PRESENT(first_col)) icol = first_col
2344 cpassert(nrow >= ncol)
2346 ALLOCATE (tau(ndim))
2348#if defined(__parallel)
2350 desca(:) = matrix_a%matrix_struct%descriptor(:)
2353 ALLOCATE (work(2*ndim))
2354 CALL pdgeqrf(nrow, ncol, a, irow, icol, desca, tau, work, lwork, info)
2355 lwork = int(work(1))
2357 ALLOCATE (work(lwork))
2358 CALL pdgeqrf(nrow, ncol, a, irow, icol, desca, tau, work, lwork, info)
2362 ALLOCATE (work(2*ndim))
2363 CALL dgeqrf(nrow, ncol, a, lda, tau, work, lwork, info)
2364 lwork = int(work(1))
2366 ALLOCATE (work(lwork))
2367 CALL dgeqrf(nrow, ncol, a, lda, tau, work, lwork, info)
2371 ALLOCATE (r_mat(ncol, ncol))
2373 IF ((myuplo ==
"U") .OR. (myuplo ==
"u"))
THEN
2376 r_mat(j, i) = 0.0_dp
2382 r_mat(i, j) = 0.0_dp
2388 DEALLOCATE (tau, work, r_mat)
2390 CALL timestop(handle)
2401 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, general_a
2403 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_solve'
2405 INTEGER :: handle, info, n, nrhs
2406 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
2407 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, a_general
2408#if defined(__parallel)
2409 INTEGER,
DIMENSION(9) :: desca, descb
2414 CALL timeset(routinen, handle)
2416 a => matrix_a%local_data
2417 a_general => general_a%local_data
2418 n = matrix_a%matrix_struct%nrow_global
2419 nrhs = general_a%matrix_struct%ncol_global
2420 ALLOCATE (ipivot(n + matrix_a%matrix_struct%nrow_block))
2422#if defined(__parallel)
2423 desca(:) = matrix_a%matrix_struct%descriptor(:)
2424 descb(:) = general_a%matrix_struct%descriptor(:)
2425 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
2426 CALL pdgetrs(
"N", n, nrhs, a, 1, 1, desca, ipivot, a_general, &
2431 ldb =
SIZE(a_general, 1)
2432 CALL dgetrf(n, n, a, lda, ipivot, info)
2433 CALL dgetrs(
"N", n, nrhs, a, lda, ipivot, a_general, ldb, info)
2439 CALL timestop(handle)
2470 SUBROUTINE cp_complex_fm_gemm(transa, transb, m, n, k, alpha, A_re, A_im, B_re, B_im, beta, &
2471 C_re, C_im, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, &
2473 CHARACTER(LEN=1),
INTENT(IN) :: transa, transb
2474 INTEGER,
INTENT(IN) :: m, n, k
2475 REAL(kind=
dp),
INTENT(IN) :: alpha
2476 TYPE(
cp_fm_type),
INTENT(IN) :: a_re, a_im, b_re, b_im
2477 REAL(kind=
dp),
INTENT(IN) :: beta
2479 INTEGER,
INTENT(IN),
OPTIONAL :: a_first_col, a_first_row, b_first_col, &
2480 b_first_row, c_first_col, c_first_row
2482 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_complex_fm_gemm'
2486 CALL timeset(routinen, handle)
2488 CALL cp_fm_gemm(transa, transb, m, n, k, alpha, a_re, b_re, beta, c_re, &
2489 a_first_col=a_first_col, &
2490 a_first_row=a_first_row, &
2491 b_first_col=b_first_col, &
2492 b_first_row=b_first_row, &
2493 c_first_col=c_first_col, &
2494 c_first_row=c_first_row)
2495 CALL cp_fm_gemm(transa, transb, m, n, k, -alpha, a_im, b_im, 1.0_dp, c_re, &
2496 a_first_col=a_first_col, &
2497 a_first_row=a_first_row, &
2498 b_first_col=b_first_col, &
2499 b_first_row=b_first_row, &
2500 c_first_col=c_first_col, &
2501 c_first_row=c_first_row)
2502 CALL cp_fm_gemm(transa, transb, m, n, k, alpha, a_re, b_im, beta, c_im, &
2503 a_first_col=a_first_col, &
2504 a_first_row=a_first_row, &
2505 b_first_col=b_first_col, &
2506 b_first_row=b_first_row, &
2507 c_first_col=c_first_col, &
2508 c_first_row=c_first_row)
2509 CALL cp_fm_gemm(transa, transb, m, n, k, alpha, a_im, b_re, 1.0_dp, c_im, &
2510 a_first_col=a_first_col, &
2511 a_first_row=a_first_row, &
2512 b_first_col=b_first_col, &
2513 b_first_row=b_first_row, &
2514 c_first_col=c_first_col, &
2515 c_first_row=c_first_row)
2517 CALL timestop(handle)
2528 SUBROUTINE cp_fm_lu_invert(matrix, info_out)
2530 INTEGER,
INTENT(OUT),
OPTIONAL :: info_out
2532 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_lu_invert'
2534 INTEGER :: nrows_global, handle, info, lwork
2535 INTEGER,
DIMENSION(:),
ALLOCATABLE :: ipivot
2536 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: mat
2537 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: mat_sp
2538 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: work
2539 REAL(kind=
sp),
DIMENSION(:),
ALLOCATABLE :: work_sp
2540#if defined(__parallel)
2542 INTEGER,
DIMENSION(9) :: desca
2543 INTEGER,
DIMENSION(:),
ALLOCATABLE :: iwork
2548 CALL timeset(routinen, handle)
2550 mat => matrix%local_data
2551 mat_sp => matrix%local_data_sp
2552 nrows_global = matrix%matrix_struct%nrow_global
2553 cpassert(nrows_global == matrix%matrix_struct%ncol_global)
2554 ALLOCATE (ipivot(nrows_global))
2556#if defined(__parallel)
2557 desca = matrix%matrix_struct%descriptor
2558 IF (matrix%use_sp)
THEN
2559 CALL psgetrf(nrows_global, nrows_global, &
2560 mat_sp, 1, 1, desca, ipivot, info)
2562 CALL pdgetrf(nrows_global, nrows_global, &
2563 mat, 1, 1, desca, ipivot, info)
2567 IF (matrix%use_sp)
THEN
2568 CALL sgetrf(nrows_global, nrows_global, &
2569 mat_sp, lda, ipivot, info)
2571 CALL dgetrf(nrows_global, nrows_global, &
2572 mat, lda, ipivot, info)
2576 CALL cp_abort(__location__,
"LU decomposition has failed")
2579 IF (matrix%use_sp)
THEN
2582 ALLOCATE (work_sp(1))
2584#if defined(__parallel)
2586 IF (matrix%use_sp)
THEN
2587 CALL psgetri(nrows_global, mat_sp, 1, 1, desca, &
2588 ipivot, work_sp, -1, iwork, -1, info)
2589 lwork = int(work_sp(1))
2590 DEALLOCATE (work_sp)
2591 ALLOCATE (work_sp(lwork))
2593 CALL pdgetri(nrows_global, mat, 1, 1, desca, &
2594 ipivot, work, -1, iwork, -1, info)
2595 lwork = int(work(1))
2597 ALLOCATE (work(lwork))
2599 liwork = int(iwork(1))
2601 ALLOCATE (iwork(liwork))
2602 IF (matrix%use_sp)
THEN
2603 CALL psgetri(nrows_global, mat_sp, 1, 1, desca, &
2604 ipivot, work_sp, lwork, iwork, liwork, info)
2606 CALL pdgetri(nrows_global, mat, 1, 1, desca, &
2607 ipivot, work, lwork, iwork, liwork, info)
2611 IF (matrix%use_sp)
THEN
2612 CALL sgetri(nrows_global, mat_sp, lda, &
2613 ipivot, work_sp, -1, info)
2614 lwork = int(work_sp(1))
2615 DEALLOCATE (work_sp)
2616 ALLOCATE (work_sp(lwork))
2617 CALL sgetri(nrows_global, mat_sp, lda, &
2618 ipivot, work_sp, lwork, info)
2620 CALL dgetri(nrows_global, mat, lda, &
2621 ipivot, work, -1, info)
2622 lwork = int(work(1))
2624 ALLOCATE (work(lwork))
2625 CALL dgetri(nrows_global, mat, lda, &
2626 ipivot, work, lwork, info)
2629 IF (matrix%use_sp)
THEN
2630 DEALLOCATE (work_sp)
2636 IF (
PRESENT(info_out))
THEN
2640 CALL cp_abort(__location__,
"LU inversion has failed")
2643 CALL timestop(handle)
2645 END SUBROUTINE cp_fm_lu_invert
2659 CHARACTER,
INTENT(IN) :: mode
2660 REAL(kind=
dp) :: res
2662 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_norm'
2664 INTEGER :: nrows, ncols, handle, lwork, nrows_local, ncols_local
2665 REAL(kind=
sp) :: res_sp
2666 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: aa
2667 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: aa_sp
2668 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: work
2669 REAL(kind=
sp),
DIMENSION(:),
ALLOCATABLE :: work_sp
2670#if defined(__parallel)
2671 INTEGER,
DIMENSION(9) :: desca
2676 CALL timeset(routinen, handle)
2679 nrow_global=nrows, &
2680 ncol_global=ncols, &
2681 nrow_local=nrows_local, &
2682 ncol_local=ncols_local)
2683 aa => matrix%local_data
2684 aa_sp => matrix%local_data_sp
2686#if defined(__parallel)
2687 desca = matrix%matrix_struct%descriptor
2691 CASE (
'1',
'O',
'o')
2695 CASE (
'F',
'f',
'E',
'e')
2698 cpabort(
"mode input is not valid")
2700 IF (matrix%use_sp)
THEN
2701 ALLOCATE (work_sp(lwork))
2702 res_sp = pslange(mode, nrows, ncols, aa_sp, 1, 1, desca, work_sp)
2703 DEALLOCATE (work_sp)
2704 res = real(res_sp, kind=
dp)
2706 ALLOCATE (work(lwork))
2707 res = pdlange(mode, nrows, ncols, aa, 1, 1, desca, work)
2714 CASE (
'1',
'O',
'o')
2718 CASE (
'F',
'f',
'E',
'e')
2721 cpabort(
"mode input is not valid")
2723 IF (matrix%use_sp)
THEN
2724 ALLOCATE (work_sp(lwork))
2725 lda =
SIZE(aa_sp, 1)
2726 res_sp = slange(mode, nrows, ncols, aa_sp, lda, work_sp)
2727 DEALLOCATE (work_sp)
2728 res = real(res_sp, kind=
dp)
2730 ALLOCATE (work(lwork))
2732 res = dlange(mode, nrows, ncols, aa, lda, work)
2737 CALL timestop(handle)
2747 FUNCTION cp_fm_latra(matrix)
RESULT(res)
2749 REAL(kind=
dp) :: res
2751 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_latra'
2753 INTEGER :: nrows, ncols, handle
2754 REAL(kind=
sp) :: res_sp
2755 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: aa
2756 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: aa_sp
2757#if defined(__parallel)
2758 INTEGER,
DIMENSION(9) :: desca
2763 CALL timeset(routinen, handle)
2765 nrows = matrix%matrix_struct%nrow_global
2766 ncols = matrix%matrix_struct%ncol_global
2767 cpassert(nrows == ncols)
2768 aa => matrix%local_data
2769 aa_sp => matrix%local_data_sp
2771#if defined(__parallel)
2772 desca = matrix%matrix_struct%descriptor
2773 IF (matrix%use_sp)
THEN
2774 res_sp = pslatra(nrows, aa_sp, 1, 1, desca)
2775 res = real(res_sp, kind=
dp)
2777 res = pdlatra(nrows, aa, 1, 1, desca)
2780 IF (matrix%use_sp)
THEN
2783 res_sp = res_sp + aa_sp(ii, ii)
2785 res = real(res_sp, kind=
dp)
2789 res = res + aa(ii, ii)
2794 CALL timestop(handle)
2796 END FUNCTION cp_fm_latra
2812 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tau
2813 INTEGER,
INTENT(IN) :: nrow, ncol, first_row, first_col
2815 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_pdgeqpf'
2818 INTEGER :: info, lwork
2819 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipiv
2820 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2821 REAL(kind=
dp),
DIMENSION(:),
POINTER :: work
2822#if defined(__parallel)
2823 INTEGER,
DIMENSION(9) :: descc
2828 CALL timeset(routinen, handle)
2830 a => matrix%local_data
2832 ALLOCATE (work(2*nrow))
2833 ALLOCATE (ipiv(ncol))
2836#if defined(__parallel)
2837 descc(:) = matrix%matrix_struct%descriptor(:)
2839 CALL pdgeqpf(nrow, ncol, a, first_row, first_col, descc, ipiv, tau, work, lwork, info)
2840 lwork = int(work(1))
2842 ALLOCATE (work(lwork))
2847 CALL pdgeqpf(nrow, ncol, a, first_row, first_col, descc, ipiv, tau, work, lwork, info)
2849 cpassert(first_row == 1 .AND. first_col == 1)
2851 CALL dgeqp3(nrow, ncol, a, lda, ipiv, tau, work, lwork, info)
2852 lwork = int(work(1))
2854 ALLOCATE (work(lwork))
2857 CALL dgeqp3(nrow, ncol, a, lda, ipiv, tau, work, lwork, info)
2864 CALL timestop(handle)
2884 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tau
2885 INTEGER,
INTENT(IN) :: nrow, first_row, first_col
2887 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_pdorgqr'
2890 INTEGER :: info, lwork
2891 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2892 REAL(kind=
dp),
DIMENSION(:),
POINTER :: work
2893#if defined(__parallel)
2894 INTEGER,
DIMENSION(9) :: descc
2899 CALL timeset(routinen, handle)
2901 a => matrix%local_data
2903 ALLOCATE (work(2*nrow))
2906#if defined(__parallel)
2907 descc(:) = matrix%matrix_struct%descriptor(:)
2909 CALL pdorgqr(nrow, nrow, nrow, a, first_row, first_col, descc, tau, work, lwork, info)
2911 lwork = int(work(1))
2913 ALLOCATE (work(lwork))
2916 CALL pdorgqr(nrow, nrow, nrow, a, first_row, first_col, descc, tau, work, lwork, info)
2918 cpassert(first_row == 1 .AND. first_col == 1)
2920 CALL dorgqr(nrow, nrow, nrow, a, lda, tau, work, lwork, info)
2921 lwork = int(work(1))
2923 ALLOCATE (work(lwork))
2924 CALL dorgqr(nrow, nrow, nrow, a, lda, tau, work, lwork, info)
2929 CALL timestop(handle)
2944 INTEGER,
INTENT(IN) :: irow, jrow
2945 REAL(
dp),
INTENT(IN) :: cs, sn
2947 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_rot_rows'
2948 INTEGER :: handle, ncol
2950#if defined(__parallel)
2951 INTEGER :: info, lwork
2952 INTEGER,
DIMENSION(9) :: desc
2953 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
2955 CALL timeset(routinen, handle)
2957#if defined(__parallel)
2958 IF (1 /= matrix%matrix_struct%context%n_pid)
THEN
2960 ALLOCATE (work(lwork))
2961 desc(:) = matrix%matrix_struct%descriptor(:)
2963 matrix%local_data(1, 1), irow, 1, desc, ncol, &
2964 matrix%local_data(1, 1), jrow, 1, desc, ncol, &
2965 cs, sn, work, lwork, info)
2970 CALL drot(ncol, matrix%local_data(irow, 1), ncol, matrix%local_data(jrow, 1), ncol, cs, sn)
2971#if defined(__parallel)
2974 CALL timestop(handle)
2988 INTEGER,
INTENT(IN) :: icol, jcol
2989 REAL(
dp),
INTENT(IN) :: cs, sn
2991 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_rot_cols'
2992 INTEGER :: handle, nrow
2994#if defined(__parallel)
2995 INTEGER :: info, lwork
2996 INTEGER,
DIMENSION(9) :: desc
2997 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
2999 CALL timeset(routinen, handle)
3001#if defined(__parallel)
3002 IF (1 /= matrix%matrix_struct%context%n_pid)
THEN
3004 ALLOCATE (work(lwork))
3005 desc(:) = matrix%matrix_struct%descriptor(:)
3007 matrix%local_data(1, 1), 1, icol, desc, 1, &
3008 matrix%local_data(1, 1), 1, jcol, desc, 1, &
3009 cs, sn, work, lwork, info)
3014 CALL drot(nrow, matrix%local_data(1, icol), 1, matrix%local_data(1, jcol), 1, cs, sn)
3015#if defined(__parallel)
3018 CALL timestop(handle)
3036 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: b
3037 INTEGER,
INTENT(IN),
OPTIONAL :: nrows, ncols, start_row, start_col
3038 LOGICAL,
INTENT(IN),
OPTIONAL :: do_norm, do_print
3040 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_Gram_Schmidt_orthonorm'
3042 INTEGER :: end_col_global, end_col_local, end_row_global, end_row_local, handle, i, j, &
3043 j_col, ncol_global, ncol_local, nrow_global, nrow_local, start_col_global, &
3044 start_col_local, start_row_global, start_row_local, this_col, unit_nr
3045 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
3046 LOGICAL :: my_do_norm, my_do_print
3047 REAL(kind=
dp) :: norm
3048 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
3050 CALL timeset(routinen, handle)
3053 IF (
PRESENT(do_norm)) my_do_norm = do_norm
3055 my_do_print = .false.
3056 IF (
PRESENT(do_print) .AND. (my_do_norm)) my_do_print = do_print
3059 IF (my_do_print)
THEN
3061 IF (unit_nr < 1) my_do_print = .false.
3064 IF (
SIZE(b) /= 0)
THEN
3065 IF (
PRESENT(nrows))
THEN
3068 nrow_global =
SIZE(b, 1)
3071 IF (
PRESENT(ncols))
THEN
3074 ncol_global =
SIZE(b, 2)
3077 IF (
PRESENT(start_row))
THEN
3078 start_row_global = start_row
3080 start_row_global = 1
3083 IF (
PRESENT(start_col))
THEN
3084 start_col_global = start_col
3086 start_col_global = 1
3089 end_row_global = start_row_global + nrow_global - 1
3090 end_col_global = start_col_global + ncol_global - 1
3093 nrow_global=nrow_global, ncol_global=ncol_global, &
3094 nrow_local=nrow_local, ncol_local=ncol_local, &
3095 row_indices=row_indices, col_indices=col_indices)
3096 IF (end_row_global > nrow_global)
THEN
3097 end_row_global = nrow_global
3099 IF (end_col_global > ncol_global)
THEN
3100 end_col_global = ncol_global
3107 DO start_row_local = 1, nrow_local
3108 IF (row_indices(start_row_local) >= start_row_global)
EXIT
3111 DO end_row_local = start_row_local, nrow_local
3112 IF (row_indices(end_row_local) > end_row_global)
EXIT
3114 end_row_local = end_row_local - 1
3116 DO start_col_local = 1, ncol_local
3117 IF (col_indices(start_col_local) >= start_col_global)
EXIT
3120 DO end_col_local = start_col_local, ncol_local
3121 IF (col_indices(end_col_local) > end_col_global)
EXIT
3123 end_col_local = end_col_local - 1
3125 a => matrix_a%local_data
3127 this_col = col_indices(start_col_local) - start_col_global + 1
3129 b(:, this_col) = a(:, start_col_local)
3131 IF (my_do_norm)
THEN
3133 b(:, this_col) = b(:, this_col)/norm
3134 IF (my_do_print)
WRITE (unit_nr,
'(I3,F8.3)') this_col, norm
3137 DO i = start_col_local + 1, end_col_local
3138 this_col = col_indices(i) - start_col_global + 1
3139 b(:, this_col) = a(:, i)
3140 DO j = start_col_local, i - 1
3141 j_col = col_indices(j) - start_col_global + 1
3142 b(:, this_col) = b(:, this_col) - &
3147 IF (my_do_norm)
THEN
3149 b(:, this_col) = b(:, this_col)/norm
3150 IF (my_do_print)
WRITE (unit_nr,
'(I3,F8.3)') this_col, norm
3154 CALL matrix_a%matrix_struct%para_env%sum(b)
3157 CALL timestop(handle)
3169 INTEGER,
INTENT(IN) :: n
3170 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
3174 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
3175 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
3176#if defined(__parallel)
3177 INTEGER,
DIMENSION(9) :: desca
3181 IF (
PRESENT(uplo)) myuplo = uplo
3183 a => fm_matrix%local_data
3184 a_sp => fm_matrix%local_data_sp
3185#if defined(__parallel)
3186 desca(:) = fm_matrix%matrix_struct%descriptor(:)
3187 IF (fm_matrix%use_sp)
THEN
3188 CALL pspotrf(myuplo, n, a_sp(1, 1), 1, 1, desca, info)
3190 CALL pdpotrf(myuplo, n, a(1, 1), 1, 1, desca, info)
3193 IF (fm_matrix%use_sp)
THEN
3194 CALL spotrf(myuplo, n, a_sp(1, 1),
SIZE(a_sp, 1), info)
3196 CALL dpotrf(myuplo, n, a(1, 1),
SIZE(a, 1), info)
3200 cpabort(
"Cholesky decomposition failed. Matrix ill-conditioned?")
3212 INTEGER,
INTENT(IN) :: n
3213 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
3216 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
3217 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
3219#if defined(__parallel)
3220 INTEGER,
DIMENSION(9) :: desca
3224 IF (
PRESENT(uplo)) myuplo = uplo
3226 a => fm_matrix%local_data
3227 a_sp => fm_matrix%local_data_sp
3228#if defined(__parallel)
3229 desca(:) = fm_matrix%matrix_struct%descriptor(:)
3230 IF (fm_matrix%use_sp)
THEN
3231 CALL pspotri(myuplo, n, a_sp(1, 1), 1, 1, desca, info)
3233 CALL pdpotri(myuplo, n, a(1, 1), 1, 1, desca, info)
3236 IF (fm_matrix%use_sp)
THEN
3237 CALL spotri(myuplo, n, a_sp(1, 1),
SIZE(a_sp, 1), info)
3239 CALL dpotri(myuplo, n, a(1, 1),
SIZE(a, 1), info)
3255 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: xv
3256 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: yv
3257 REAL(kind=
dp),
OPTIONAL,
INTENT(IN) :: alpha, beta
3259 INTEGER :: na, nc, nx, ny
3260 REAL(kind=
dp) :: aval, bval
3261#if defined(__parallel)
3262 INTEGER :: nrl, ncl, ic, ir
3263 INTEGER,
DIMENSION(:),
POINTER :: rind, cind
3264 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: xvl, yvl, yvm
3267 IF (amat%use_sp)
THEN
3268 cpabort(
"cp_fm_matvec: SP option not available")
3271 IF (
PRESENT(alpha)) aval = alpha
3273 IF (
PRESENT(beta)) bval = beta
3278 IF ((nx /= ny) .OR. (nc /= nx))
THEN
3279 cpabort(
"cp_fm_matvec: incompatible dimensions")
3281#if defined(__parallel)
3283 row_indices=rind, col_indices=cind)
3284 ALLOCATE (xvl(ncl), yvl(nrl), yvm(ny))
3286 xvl(ic) = xv(cind(ic))
3288 yvl(1:nrl) = matmul(amat%local_data, xvl(1:ncl))
3291 yvm(rind(ir)) = yvl(ir)
3293 CALL amat%matrix_struct%para_env%sum(yvm)
3294 IF (bval == 0.0_dp)
THEN
3297 yv = bval*yv + aval*yvm
3300 IF (bval == 0.0_dp)
THEN
3301 yv = aval*matmul(amat%local_data, xv)
3303 yv = bval*yv + aval*matmul(amat%local_data, xv)
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
methods related to the blacs parallel environment
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_rot_rows(matrix, irow, jrow, cs, sn)
Applies a planar rotation defined by cs and sn to the i'th and j'th rows.
subroutine, public cp_fm_row_scale(matrixa, scaling)
scales row i of matrix a with scaling(i)
subroutine, public cp_fm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, c_first_row)
computes matrix_c = beta * matrix_c + alpha * ( matrix_a ** transa ) * ( matrix_b ** transb )
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
subroutine, public cp_fm_add_columns(msource, mtarget, ncol, alpha, source_start, target_start)
Add (and scale) a subset of columns of a fm to a fm b = alpha*a + b.
subroutine, public cp_fm_rot_cols(matrix, icol, jcol, cs, sn)
Applies a planar rotation defined by cs and sn to the i'th and j'th columnns.
subroutine, public cp_fm_solve(matrix_a, general_a)
computes the the solution to A*b=A_general using lu decomposition
subroutine, public cp_fm_pdgeqpf(matrix, tau, nrow, ncol, first_row, first_col)
compute a QR factorization with column pivoting of a M-by-N distributed matrix sub( A ) = A(IA:IA+M-1...
real(kind=dp) function, public cp_fm_frobenius_norm(matrix_a)
computes the Frobenius norm of matrix_a
subroutine, public cp_fm_det(matrix_a, det_a)
Computes the determinant (with a correct sign even in parallel environment!) of a real square matrix.
subroutine, public cp_fm_transpose(matrix, matrixt)
transposes a matrix matrixt = matrix ^ T
subroutine, public cp_fm_qr_factorization(matrix_a, matrix_r, nrow_fact, ncol_fact, first_row, first_col, uplo)
performs a QR factorization of the input rectangular matrix A or of a submatrix of A the computed tri...
subroutine, public cp_fm_gram_schmidt_orthonorm(matrix_a, b, nrows, ncols, start_row, start_col, do_norm, do_print)
Orthonormalizes selected rows and columns of a full matrix, matrix_a.
subroutine, public cp_fm_syrk(uplo, trans, k, alpha, matrix_a, ia, ja, beta, matrix_c)
performs a rank-k update of a symmetric matrix_c matrix_c = beta * matrix_c + alpha * matrix_a * tran...
subroutine, public cp_fm_potrf(fm_matrix, n, uplo)
Cholesky decomposition.
subroutine, public cp_fm_potri(fm_matrix, n, uplo)
Invert trianguar matrix.
subroutine, public cp_fm_geadd(alpha, trans, matrix_a, beta, matrix_b)
interface to BLACS geadd: matrix_b = beta*matrix_b + alpha*opt(matrix_a) where opt(matrix_a) can be e...
subroutine, public cp_fm_schur_product(matrix_a, matrix_b, matrix_c)
computes the schur product of two matrices c_ij = a_ij * b_ij
real(kind=dp) function, public cp_fm_norm(matrix, mode)
norm of matrix using (p)dlange
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_uplo_to_full(matrix, work, uplo)
given a triangular matrix according to uplo, computes the corresponding full matrix
subroutine, public cp_fm_invert(matrix_a, matrix_inverse, det_a, eps_svd, eigval)
Inverts a cp_fm_type matrix, optionally returning the determinant of the input matrix.
subroutine, public cp_complex_fm_gemm(transa, transb, m, n, k, alpha, a_re, a_im, b_re, b_im, beta, c_re, c_im, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, c_first_row)
Convenience function. Computes the matrix multiplications needed for the multiplication of complex ma...
subroutine, public cp_fm_scale(alpha, matrix_a)
scales a matrix matrix_a = alpha * matrix_b
subroutine, public cp_fm_triangular_invert(matrix_a, uplo_tr)
inverts a triangular matrix
subroutine, public cp_fm_symm(side, uplo, m, n, alpha, matrix_a, matrix_b, beta, matrix_c)
computes matrix_c = beta * matrix_c + alpha * matrix_a * matrix_b computes matrix_c = beta * matrix_c...
subroutine, public cp_fm_matvec(amat, xv, yv, alpha, beta)
Calculates yv = alpha*amat*xv + beta*yv where amat: fm matrix xv : vector replicated yv : vector repl...
subroutine, public cp_fm_triangular_multiply(triangular_matrix, matrix_b, side, transpose_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, alpha)
multiplies in place by a triangular matrix: matrix_b = alpha op(triangular_matrix) matrix_b or (if si...
subroutine, public cp_fm_pdorgqr(matrix, tau, nrow, first_row, first_col)
generates an M-by-N real distributed matrix Q denoting A(IA:IA+M-1,JA:JA+N-1) with orthonormal column...
represent the structure of a full matrix
logical function, public cp_fm_struct_equivalent(fmstruct1, fmstruct2)
returns true if the two matrix structures are equivalent, false otherwise.
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_diag(matrix, diag)
returns the diagonal elements of a fm
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, use_sp, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_set_submatrix(fm, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
sets a submatrix of a full matrix fm(start_row:start_row+n_rows,start_col:start_col+n_cols) = alpha*o...
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
subroutine, public cp_fm_set_element(matrix, irow_global, icol_global, alpha)
sets an element of a matrix
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public sp
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_memory(mem)
Returns the total amount of memory [bytes] in use, if known, zero otherwise.
Collection of simple mathematical functions and subroutines.
subroutine, public get_pseudo_inverse_svd(a, a_pinverse, rskip, determinant, sval)
returns the pseudoinverse of a real, square matrix using singular value decomposition
subroutine, public diag(n, a, d, v)
Diagonalize matrix a. The eigenvalues are returned in vector d and the eigenvectors are returned in m...
Interface to the message passing library MPI.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
just to build arrays of pointers to matrices