32#include "../base/base_uses.f90"
37 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
38 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_fm_basic_linalg'
72 REAL(KIND=
dp),
EXTERNAL :: dlange, pdlange, pdlatra
73 REAL(KIND=
sp),
EXTERNAL :: slange, pslange, pslatra
76 MODULE PROCEDURE cp_fm_trace_a0b0t0
77 MODULE PROCEDURE cp_fm_trace_a1b0t1_a
78 MODULE PROCEDURE cp_fm_trace_a1b0t1_p
79 MODULE PROCEDURE cp_fm_trace_a1b1t1_aa
80 MODULE PROCEDURE cp_fm_trace_a1b1t1_ap
81 MODULE PROCEDURE cp_fm_trace_a1b1t1_pa
82 MODULE PROCEDURE cp_fm_trace_a1b1t1_pp
86 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_aa
87 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_ap
88 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_pa
89 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_pp
100 REAL(kind=
dp),
INTENT(OUT) :: det_a
101 REAL(kind=
dp) :: determinant
103 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
104 INTEGER :: n, i, info, p
105 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
106 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
diag
108#if defined(__parallel)
109 INTEGER :: myprow, nprow, npcol, nrow_local, nrow_block, irow_local
110 INTEGER,
DIMENSION(9) :: desca
114 matrix_struct=matrix_a%matrix_struct, &
118 a => matrix_lu%local_data
119 n = matrix_lu%matrix_struct%nrow_global
125#if defined(__parallel)
127 desca(:) = matrix_lu%matrix_struct%descriptor(:)
128 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
130 determinant = product(
diag)
131 myprow = matrix_lu%matrix_struct%context%mepos(1)
132 nprow = matrix_lu%matrix_struct%context%num_pe(1)
133 npcol = matrix_lu%matrix_struct%context%num_pe(2)
134 nrow_local = matrix_lu%matrix_struct%nrow_locals(myprow)
135 nrow_block = matrix_lu%matrix_struct%nrow_block
136 DO irow_local = 1, nrow_local
137 i = matrix_lu%matrix_struct%row_indices(irow_local)
138 IF (ipivot(irow_local) /= i) p = p + 1
140 CALL matrix_lu%matrix_struct%para_env%sum(p)
144 CALL dgetrf(n, n, a, n, ipivot, info)
146 determinant = product(
diag)
148 IF (ipivot(i) /= i) p = p + 1
154 det_a = determinant*(-2*mod(p, 2) + 1.0_dp)
168 REAL(kind=
dp),
INTENT(IN) :: alpha
170 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: beta
171 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_b
173 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_scale_and_add'
175 INTEGER :: handle, size_a, size_b
176 REAL(kind=
dp) :: my_beta
177 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
178 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp, b_sp
180 CALL timeset(routinen, handle)
183 IF (
PRESENT(matrix_b)) my_beta = 1.0_dp
184 IF (
PRESENT(beta)) my_beta = beta
187 IF (
PRESENT(beta))
THEN
188 cpassert(
PRESENT(matrix_b))
189 IF (
ASSOCIATED(matrix_a%local_data, matrix_b%local_data))
THEN
190 cpwarn(
"Bad use of routine. Call cp_fm_scale instead")
192 CALL timestop(handle)
197 a => matrix_a%local_data
198 a_sp => matrix_a%local_data_sp
200 IF (matrix_a%use_sp)
THEN
201 size_a =
SIZE(a_sp, 1)*
SIZE(a_sp, 2)
203 size_a =
SIZE(a, 1)*
SIZE(a, 2)
206 IF (alpha /= 1.0_dp)
THEN
207 IF (matrix_a%use_sp)
THEN
208 CALL sscal(size_a, real(alpha,
sp), a_sp, 1)
210 CALL dscal(size_a, alpha, a, 1)
213 IF (my_beta /= 0.0_dp)
THEN
214 IF (matrix_a%matrix_struct%context /= matrix_b%matrix_struct%context) &
215 cpabort(
"Matrices must be in the same blacs context")
218 matrix_b%matrix_struct))
THEN
220 b => matrix_b%local_data
221 b_sp => matrix_b%local_data_sp
222 IF (matrix_b%use_sp)
THEN
223 size_b =
SIZE(b_sp, 1)*
SIZE(b_sp, 2)
225 size_b =
SIZE(b, 1)*
SIZE(b, 2)
227 IF (size_a /= size_b) &
228 cpabort(
"Matrices must have same local sizes")
230 IF (matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
231 CALL saxpy(size_a, real(my_beta,
sp), b_sp, 1, a_sp, 1)
232 ELSEIF (matrix_a%use_sp .AND. .NOT. matrix_b%use_sp)
THEN
233 CALL saxpy(size_a, real(my_beta,
sp), real(b,
sp), 1, a_sp, 1)
234 ELSEIF (.NOT. matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
235 CALL daxpy(size_a, my_beta, real(b_sp,
dp), 1, a, 1)
237 CALL daxpy(size_a, my_beta, b, 1, a, 1)
242 cpabort(
"to do (pdscal,pdcopy,pdaxpy)")
250 CALL timestop(handle)
271 REAL(kind=
dp),
INTENT(IN) :: alpha, beta
272 CHARACTER,
INTENT(IN) :: trans
273 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
275 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_geadd'
277 INTEGER :: nrow_global, ncol_global, handle
278 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: aa, bb
279#if defined(__parallel)
280 INTEGER,
DIMENSION(9) :: desca, descb
285 CALL timeset(routinen, handle)
287 nrow_global = matrix_a%matrix_struct%nrow_global
288 ncol_global = matrix_a%matrix_struct%ncol_global
289 cpassert(nrow_global == matrix_b%matrix_struct%nrow_global)
290 cpassert(ncol_global == matrix_b%matrix_struct%ncol_global)
292 aa => matrix_a%local_data
293 bb => matrix_b%local_data
295#if defined(__parallel)
296 desca = matrix_a%matrix_struct%descriptor
297 descb = matrix_b%matrix_struct%descriptor
298 CALL pdgeadd(trans, &
310 CALL mkl_domatadd(
'C', trans,
'N', nrow_global, ncol_global, &
311 alpha, aa, nrow_global, beta, bb, nrow_global, bb, nrow_global)
317 DO jj = 1, ncol_global
318 DO ii = 1, nrow_global
319 bb(ii, jj) = beta*bb(ii, jj) + alpha*aa(jj, ii)
323 DO jj = 1, ncol_global
324 DO ii = 1, nrow_global
325 bb(ii, jj) = beta*bb(ii, jj) + alpha*aa(ii, jj)
331 CALL timestop(handle)
347 TYPE(
cp_fm_type),
INTENT(IN) :: msource, mtarget
348 INTEGER,
INTENT(IN) :: ncol
349 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: alpha
350 INTEGER,
INTENT(IN),
OPTIONAL :: source_start, target_start
352 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_add_columns'
354 INTEGER :: handle, n, ss, ts, i
355 REAL(kind=
dp) :: fscale
356 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
357#if defined(__parallel)
358 INTEGER,
DIMENSION(9) :: desca, descb
361 CALL timeset(routinen, handle)
366 IF (
PRESENT(source_start)) ss = source_start
367 IF (
PRESENT(target_start)) ts = target_start
370 IF (
PRESENT(alpha)) fscale = alpha
372 n = msource%matrix_struct%nrow_global
374 a => msource%local_data
375 b => mtarget%local_data
377#if defined(__parallel)
379 desca(:) = msource%matrix_struct%descriptor(:)
380 descb(:) = mtarget%matrix_struct%descriptor(:)
381 CALL pdgeadd(
"N", n, ncol, fscale, a, 1, ss, desca, 1.0_dp, b, 1, ts, descb)
384 b(1:n, ts + i) = b(1:n, ts + i) + fscale*a(1:n, ss + i)
388 CALL timestop(handle)
409 SUBROUTINE cp_fm_lu_decompose(matrix_a, almost_determinant, correct_sign)
411 REAL(kind=
dp),
INTENT(OUT) :: almost_determinant
412 LOGICAL,
INTENT(IN),
OPTIONAL :: correct_sign
414 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_lu_decompose'
416 INTEGER :: handle, i, info, n
417 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
418 REAL(kind=
dp) :: determinant
419 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
420#if defined(__parallel)
421 INTEGER,
DIMENSION(9) :: desca
422 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
diag
427 CALL timeset(routinen, handle)
429 a => matrix_a%local_data
430 n = matrix_a%matrix_struct%nrow_global
431 ALLOCATE (ipivot(n + matrix_a%matrix_struct%nrow_block))
433#if defined(__parallel)
434 mark_used(correct_sign)
435 desca(:) = matrix_a%matrix_struct%descriptor(:)
436 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
443 determinant = determinant*
diag(i)
448 CALL dgetrf(n, n, a, lda, ipivot, info)
450 IF (correct_sign)
THEN
452 IF (ipivot(i) /= i)
THEN
453 determinant = -determinant*a(i, i)
455 determinant = determinant*a(i, i)
460 determinant = determinant*a(i, i)
467 almost_determinant = determinant
468 CALL timestop(handle)
469 END SUBROUTINE cp_fm_lu_decompose
494 SUBROUTINE cp_fm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, &
495 matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, &
496 c_first_col, c_first_row)
498 CHARACTER(LEN=1),
INTENT(IN) :: transa, transb
499 INTEGER,
INTENT(IN) :: m, n, k
500 REAL(kind=
dp),
INTENT(IN) :: alpha
501 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
502 REAL(kind=
dp),
INTENT(IN) :: beta
504 INTEGER,
INTENT(IN),
OPTIONAL :: a_first_col, a_first_row, &
505 b_first_col, b_first_row, &
506 c_first_col, c_first_row
508 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_gemm'
510 INTEGER :: handle, i_a, i_b, i_c, j_a, &
512 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b, c
513 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp, b_sp, c_sp
514#if defined(__parallel)
515 INTEGER,
DIMENSION(9) :: desca, descb, descc
517 INTEGER :: lda, ldb, ldc
520 CALL timeset(routinen, handle)
525 a => matrix_a%local_data
526 b => matrix_b%local_data
527 c => matrix_c%local_data
529 a_sp => matrix_a%local_data_sp
530 b_sp => matrix_b%local_data_sp
531 c_sp => matrix_c%local_data_sp
534 IF (
PRESENT(a_first_row)) i_a = a_first_row
537 IF (
PRESENT(a_first_col)) j_a = a_first_col
540 IF (
PRESENT(b_first_row)) i_b = b_first_row
543 IF (
PRESENT(b_first_col)) j_b = b_first_col
546 IF (
PRESENT(c_first_row)) i_c = c_first_row
549 IF (
PRESENT(c_first_col)) j_c = c_first_col
551#if defined(__parallel)
553 desca(:) = matrix_a%matrix_struct%descriptor(:)
554 descb(:) = matrix_b%matrix_struct%descriptor(:)
555 descc(:) = matrix_c%matrix_struct%descriptor(:)
557 IF (matrix_a%use_sp .AND. matrix_b%use_sp .AND. matrix_c%use_sp)
THEN
559 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, &
560 descb, real(beta,
sp), c_sp(1, 1), i_c, j_c, descc)
562 ELSEIF ((.NOT. matrix_a%use_sp) .AND. (.NOT. matrix_b%use_sp) .AND. (.NOT. matrix_c%use_sp))
THEN
564 CALL pdgemm(transa, transb, m, n, k, alpha, a, i_a, j_a, desca, b, i_b, j_b, &
565 descb, beta, c, i_c, j_c, descc)
568 cpabort(
"Mixed precision gemm NYI")
572 IF (matrix_a%use_sp .AND. matrix_b%use_sp .AND. matrix_c%use_sp)
THEN
578 CALL sgemm(transa, transb, m, n, k, real(alpha,
sp), a_sp(i_a, j_a), lda, b_sp(i_b, j_b), ldb, &
579 REAL(beta,
sp), c_sp(i_c, j_c), ldc)
581 ELSEIF ((.NOT. matrix_a%use_sp) .AND. (.NOT. matrix_b%use_sp) .AND. (.NOT. matrix_c%use_sp))
THEN
587 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)
590 cpabort(
"Mixed precision gemm NYI")
594 CALL timestop(handle)
619 SUBROUTINE cp_fm_symm(side, uplo, m, n, alpha, matrix_a, matrix_b, beta, matrix_c)
621 CHARACTER(LEN=1),
INTENT(IN) :: side, uplo
622 INTEGER,
INTENT(IN) :: m, n
623 REAL(kind=
dp),
INTENT(IN) :: alpha
624 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
625 REAL(kind=
dp),
INTENT(IN) :: beta
628 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_symm'
631 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b, c
632#if defined(__parallel)
633 INTEGER,
DIMENSION(9) :: desca, descb, descc
635 INTEGER :: lda, ldb, ldc
638 CALL timeset(routinen, handle)
640 a => matrix_a%local_data
641 b => matrix_b%local_data
642 c => matrix_c%local_data
644#if defined(__parallel)
646 desca(:) = matrix_a%matrix_struct%descriptor(:)
647 descb(:) = matrix_b%matrix_struct%descriptor(:)
648 descc(:) = matrix_c%matrix_struct%descriptor(:)
650 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)
654 lda = matrix_a%matrix_struct%local_leading_dimension
655 ldb = matrix_b%matrix_struct%local_leading_dimension
656 ldc = matrix_c%matrix_struct%local_leading_dimension
658 CALL dsymm(side, uplo, m, n, alpha, a(1, 1), lda, b(1, 1), ldb, beta, c(1, 1), ldc)
661 CALL timestop(handle)
674 REAL(kind=
dp) :: norm
676 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_frobenius_norm'
678 INTEGER :: handle, size_a
679 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
680 REAL(kind=
dp),
EXTERNAL :: ddot
681#if defined(__parallel)
685 CALL timeset(routinen, handle)
688 a => matrix_a%local_data
689 size_a =
SIZE(a, 1)*
SIZE(a, 2)
690 norm = ddot(size_a, a(1, 1), 1, a(1, 1), 1)
691#if defined(__parallel)
692 group = matrix_a%matrix_struct%para_env
697 CALL timestop(handle)
716 SUBROUTINE cp_fm_syrk(uplo, trans, k, alpha, matrix_a, ia, ja, beta, matrix_c)
717 CHARACTER(LEN=1),
INTENT(IN) :: uplo, trans
718 INTEGER,
INTENT(IN) :: k
719 REAL(kind=
dp),
INTENT(IN) :: alpha
721 INTEGER,
INTENT(IN) :: ia, ja
722 REAL(kind=
dp),
INTENT(IN) :: beta
725 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_syrk'
728 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, c
729#if defined(__parallel)
730 INTEGER,
DIMENSION(9) :: desca, descc
735 CALL timeset(routinen, handle)
737 n = matrix_c%matrix_struct%nrow_global
739 a => matrix_a%local_data
740 c => matrix_c%local_data
742#if defined(__parallel)
744 desca(:) = matrix_a%matrix_struct%descriptor(:)
745 descc(:) = matrix_c%matrix_struct%descriptor(:)
747 CALL pdsyrk(uplo, trans, n, k, alpha, a(1, 1), ia, ja, desca, beta, c(1, 1), 1, 1, descc)
754 CALL dsyrk(uplo, trans, n, k, alpha, a(ia, ja), lda, beta, c(1, 1), ldc)
757 CALL timestop(handle)
771 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b, matrix_c
773 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_schur_product'
775 INTEGER :: handle, icol_local, irow_local, mypcol, &
776 myprow, ncol_local, &
778 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b, c
781 CALL timeset(routinen, handle)
783 context => matrix_a%matrix_struct%context
784 myprow = context%mepos(1)
785 mypcol = context%mepos(2)
787 a => matrix_a%local_data
788 b => matrix_b%local_data
789 c => matrix_c%local_data
791 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
792 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
794 DO icol_local = 1, ncol_local
795 DO irow_local = 1, nrow_local
796 c(irow_local, icol_local) = a(irow_local, icol_local)*b(irow_local, icol_local)
800 CALL timestop(handle)
817 SUBROUTINE cp_fm_trace_a0b0t0(matrix_a, matrix_b, trace)
819 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
820 REAL(KIND=
dp),
INTENT(OUT) :: trace
822 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a0b0t0'
824 INTEGER :: handle, mypcol, myprow, ncol_local, &
826 REAL(KIND=
dp),
DIMENSION(:, :),
POINTER :: a, b
827 REAL(KIND=
sp),
DIMENSION(:, :),
POINTER :: a_sp, b_sp
831 CALL timeset(routinen, handle)
833 context => matrix_a%matrix_struct%context
834 myprow = context%mepos(1)
835 mypcol = context%mepos(2)
837 group = matrix_a%matrix_struct%para_env
839 a => matrix_a%local_data
840 b => matrix_b%local_data
842 a_sp => matrix_a%local_data_sp
843 b_sp => matrix_b%local_data_sp
845 nrow_local = min(matrix_a%matrix_struct%nrow_locals(myprow), matrix_b%matrix_struct%nrow_locals(myprow))
846 ncol_local = min(matrix_a%matrix_struct%ncol_locals(mypcol), matrix_b%matrix_struct%ncol_locals(mypcol))
849 IF (matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
850 trace =
accurate_sum(real(a_sp(1:nrow_local, 1:ncol_local)* &
851 b_sp(1:nrow_local, 1:ncol_local),
dp))
852 ELSEIF (matrix_a%use_sp .AND. .NOT. matrix_b%use_sp)
THEN
853 trace =
accurate_sum(real(a_sp(1:nrow_local, 1:ncol_local),
dp)* &
854 b(1:nrow_local, 1:ncol_local))
855 ELSEIF (.NOT. matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
857 REAL(b_sp(1:nrow_local, 1:ncol_local), dp))
860 b(1:nrow_local, 1:ncol_local))
863 CALL group%sum(trace)
865 CALL timestop(handle)
867 END SUBROUTINE cp_fm_trace_a0b0t0
888 SUBROUTINE cp_fm_trace_a1b0t1_a (matrix_a, matrix_b, trace)
889 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
891 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
893 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b0t1_a'
895 INTEGER :: handle, imatrix, n_matrices, &
896 ncols_local, nrows_local
897 LOGICAL :: use_sp_a, use_sp_b
898 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
899 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
902 CALL timeset(routinen, handle)
904 n_matrices =
SIZE(trace)
905 cpassert(
SIZE(matrix_a) == n_matrices)
907 CALL cp_fm_get_info(matrix_b, nrow_local=nrows_local, ncol_local=ncols_local)
908 use_sp_b = matrix_b%use_sp
911 ldata_b_sp => matrix_b%local_data_sp(1:nrows_local, 1:ncols_local)
913 ldata_b => matrix_b%local_data(1:nrows_local, 1:ncols_local)
921 DO imatrix = 1, n_matrices
923 use_sp_a = matrix_a(imatrix) %use_sp
926 IF (use_sp_a .AND. use_sp_b)
THEN
927 ldata_a_sp => matrix_a(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
929 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
930 ldata_a => matrix_a(imatrix) %local_data(1:nrows_local, 1:ncols_local)
933 cpabort(
"Matrices A and B are of different types")
938 group = matrix_b%matrix_struct%para_env
939 CALL group%sum(trace)
941 CALL timestop(handle)
942 END SUBROUTINE cp_fm_trace_a1b0t1_a
943 SUBROUTINE cp_fm_trace_a1b0t1_p (matrix_a, matrix_b, trace)
944 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
946 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
948 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b0t1_p'
950 INTEGER :: handle, imatrix, n_matrices, &
951 ncols_local, nrows_local
952 LOGICAL :: use_sp_a, use_sp_b
953 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
954 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
957 CALL timeset(routinen, handle)
959 n_matrices =
SIZE(trace)
960 cpassert(
SIZE(matrix_a) == n_matrices)
962 CALL cp_fm_get_info(matrix_b, nrow_local=nrows_local, ncol_local=ncols_local)
963 use_sp_b = matrix_b%use_sp
966 ldata_b_sp => matrix_b%local_data_sp(1:nrows_local, 1:ncols_local)
968 ldata_b => matrix_b%local_data(1:nrows_local, 1:ncols_local)
976 DO imatrix = 1, n_matrices
978 use_sp_a = matrix_a(imatrix) %matrix%use_sp
981 IF (use_sp_a .AND. use_sp_b)
THEN
982 ldata_a_sp => matrix_a(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
984 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
985 ldata_a => matrix_a(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
988 cpabort(
"Matrices A and B are of different types")
993 group = matrix_b%matrix_struct%para_env
994 CALL group%sum(trace)
996 CALL timestop(handle)
997 END SUBROUTINE cp_fm_trace_a1b0t1_p
1017 SUBROUTINE cp_fm_trace_a1b1t1_aa (matrix_a, matrix_b, trace, accurate)
1018 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1019 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1020 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1021 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1023 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_aa'
1025 INTEGER :: handle, imatrix, n_matrices, &
1026 ncols_local, nrows_local
1027 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1028 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1029 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1032 CALL timeset(routinen, handle)
1034 n_matrices =
SIZE(trace)
1035 cpassert(
SIZE(matrix_a) == n_matrices)
1036 cpassert(
SIZE(matrix_b) == n_matrices)
1038 use_accurate_sum = .true.
1039 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1045 DO imatrix = 1, n_matrices
1046 CALL cp_fm_get_info(matrix_a(imatrix) , nrow_local=nrows_local, ncol_local=ncols_local)
1048 use_sp_a = matrix_a(imatrix) %use_sp
1049 use_sp_b = matrix_b(imatrix) %use_sp
1052 IF (use_sp_a .AND. use_sp_b)
THEN
1053 ldata_a_sp => matrix_a(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1054 ldata_b_sp => matrix_b(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1055 IF (use_accurate_sum)
THEN
1058 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1060 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1061 ldata_a => matrix_a(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1062 ldata_b => matrix_b(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1063 IF (use_accurate_sum)
THEN
1066 trace(imatrix) = sum(ldata_a*ldata_b)
1069 cpabort(
"Matrices A and B are of different types")
1074 group = matrix_a(1) %matrix_struct%para_env
1075 CALL group%sum(trace)
1077 CALL timestop(handle)
1078 END SUBROUTINE cp_fm_trace_a1b1t1_aa
1079 SUBROUTINE cp_fm_trace_a1b1t1_ap (matrix_a, matrix_b, trace, accurate)
1080 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1081 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1082 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1083 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1085 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_ap'
1087 INTEGER :: handle, imatrix, n_matrices, &
1088 ncols_local, nrows_local
1089 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1090 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1091 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1094 CALL timeset(routinen, handle)
1096 n_matrices =
SIZE(trace)
1097 cpassert(
SIZE(matrix_a) == n_matrices)
1098 cpassert(
SIZE(matrix_b) == n_matrices)
1100 use_accurate_sum = .true.
1101 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1107 DO imatrix = 1, n_matrices
1108 CALL cp_fm_get_info(matrix_a(imatrix) , nrow_local=nrows_local, ncol_local=ncols_local)
1110 use_sp_a = matrix_a(imatrix) %use_sp
1111 use_sp_b = matrix_b(imatrix) %matrix%use_sp
1114 IF (use_sp_a .AND. use_sp_b)
THEN
1115 ldata_a_sp => matrix_a(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1116 ldata_b_sp => matrix_b(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1117 IF (use_accurate_sum)
THEN
1120 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1122 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1123 ldata_a => matrix_a(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1124 ldata_b => matrix_b(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1125 IF (use_accurate_sum)
THEN
1128 trace(imatrix) = sum(ldata_a*ldata_b)
1131 cpabort(
"Matrices A and B are of different types")
1136 group = matrix_a(1) %matrix_struct%para_env
1137 CALL group%sum(trace)
1139 CALL timestop(handle)
1140 END SUBROUTINE cp_fm_trace_a1b1t1_ap
1141 SUBROUTINE cp_fm_trace_a1b1t1_pa (matrix_a, matrix_b, trace, accurate)
1142 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1143 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1144 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1145 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1147 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_pa'
1149 INTEGER :: handle, imatrix, n_matrices, &
1150 ncols_local, nrows_local
1151 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1152 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1153 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1156 CALL timeset(routinen, handle)
1158 n_matrices =
SIZE(trace)
1159 cpassert(
SIZE(matrix_a) == n_matrices)
1160 cpassert(
SIZE(matrix_b) == n_matrices)
1162 use_accurate_sum = .true.
1163 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1169 DO imatrix = 1, n_matrices
1170 CALL cp_fm_get_info(matrix_a(imatrix) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1172 use_sp_a = matrix_a(imatrix) %matrix%use_sp
1173 use_sp_b = matrix_b(imatrix) %use_sp
1176 IF (use_sp_a .AND. use_sp_b)
THEN
1177 ldata_a_sp => matrix_a(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1178 ldata_b_sp => matrix_b(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1179 IF (use_accurate_sum)
THEN
1182 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1184 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1185 ldata_a => matrix_a(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1186 ldata_b => matrix_b(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1187 IF (use_accurate_sum)
THEN
1190 trace(imatrix) = sum(ldata_a*ldata_b)
1193 cpabort(
"Matrices A and B are of different types")
1198 group = matrix_a(1) %matrix%matrix_struct%para_env
1199 CALL group%sum(trace)
1201 CALL timestop(handle)
1202 END SUBROUTINE cp_fm_trace_a1b1t1_pa
1203 SUBROUTINE cp_fm_trace_a1b1t1_pp (matrix_a, matrix_b, trace, accurate)
1204 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1205 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1206 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1207 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1209 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_pp'
1211 INTEGER :: handle, imatrix, n_matrices, &
1212 ncols_local, nrows_local
1213 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1214 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1215 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1218 CALL timeset(routinen, handle)
1220 n_matrices =
SIZE(trace)
1221 cpassert(
SIZE(matrix_a) == n_matrices)
1222 cpassert(
SIZE(matrix_b) == n_matrices)
1224 use_accurate_sum = .true.
1225 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1231 DO imatrix = 1, n_matrices
1232 CALL cp_fm_get_info(matrix_a(imatrix) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1234 use_sp_a = matrix_a(imatrix) %matrix%use_sp
1235 use_sp_b = matrix_b(imatrix) %matrix%use_sp
1238 IF (use_sp_a .AND. use_sp_b)
THEN
1239 ldata_a_sp => matrix_a(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1240 ldata_b_sp => matrix_b(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1241 IF (use_accurate_sum)
THEN
1244 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1246 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1247 ldata_a => matrix_a(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1248 ldata_b => matrix_b(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1249 IF (use_accurate_sum)
THEN
1252 trace(imatrix) = sum(ldata_a*ldata_b)
1255 cpabort(
"Matrices A and B are of different types")
1260 group = matrix_a(1) %matrix%matrix_struct%para_env
1261 CALL group%sum(trace)
1263 CALL timestop(handle)
1264 END SUBROUTINE cp_fm_trace_a1b1t1_pp
1273 SUBROUTINE cp_fm_contracted_trace_a2b2t2_aa (matrix_a, matrix_b, trace, accurate)
1274 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1275 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1276 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1277 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1279 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_aa'
1281 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1283 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1284 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1286 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1287 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1290 CALL timeset(routinen, handle)
1292 nz =
SIZE(matrix_a, 1)
1293 cpassert(
SIZE(matrix_b, 1) == nz)
1295 na =
SIZE(matrix_a, 2)
1296 nb =
SIZE(matrix_b, 2)
1297 cpassert(
SIZE(trace, 1) == na)
1298 cpassert(
SIZE(trace, 2) == nb)
1300 use_accurate_sum = .true.
1301 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1306 na8 = int(na, kind=
int_8)
1312 DO itrace = 1, ntraces
1313 ib8 = (itrace - 1)/na8
1314 ia = int(itrace - ib8*na8)
1319 CALL cp_fm_get_info(matrix_a(iz, ia) , nrow_local=nrows_local, ncol_local=ncols_local)
1320 use_sp_a = matrix_a(iz, ia) %use_sp
1321 use_sp_b = matrix_b(iz, ib) %use_sp
1324 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1325 ldata_a => matrix_a(iz, ia) %local_data(1:nrows_local, 1:ncols_local)
1326 ldata_b => matrix_b(iz, ib) %local_data(1:nrows_local, 1:ncols_local)
1327 IF (use_accurate_sum)
THEN
1330 t = t + sum(ldata_a*ldata_b)
1332 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1333 ldata_a_sp => matrix_a(iz, ia) %local_data_sp(1:nrows_local, 1:ncols_local)
1334 ldata_b_sp => matrix_b(iz, ib) %local_data_sp(1:nrows_local, 1:ncols_local)
1335 IF (use_accurate_sum)
THEN
1338 t = t + sum(ldata_a_sp*ldata_b_sp)
1341 cpabort(
"Matrices A and B are of different types")
1348 group = matrix_a(1, 1) %matrix_struct%para_env
1349 CALL group%sum(trace)
1351 CALL timestop(handle)
1352 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_aa
1353 SUBROUTINE cp_fm_contracted_trace_a2b2t2_ap (matrix_a, matrix_b, trace, accurate)
1354 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1355 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1356 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1357 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1359 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_ap'
1361 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1363 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1364 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1366 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1367 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1370 CALL timeset(routinen, handle)
1372 nz =
SIZE(matrix_a, 1)
1373 cpassert(
SIZE(matrix_b, 1) == nz)
1375 na =
SIZE(matrix_a, 2)
1376 nb =
SIZE(matrix_b, 2)
1377 cpassert(
SIZE(trace, 1) == na)
1378 cpassert(
SIZE(trace, 2) == nb)
1380 use_accurate_sum = .true.
1381 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1386 na8 = int(na, kind=
int_8)
1392 DO itrace = 1, ntraces
1393 ib8 = (itrace - 1)/na8
1394 ia = int(itrace - ib8*na8)
1399 CALL cp_fm_get_info(matrix_a(iz, ia) , nrow_local=nrows_local, ncol_local=ncols_local)
1400 use_sp_a = matrix_a(iz, ia) %use_sp
1401 use_sp_b = matrix_b(iz, ib) %matrix%use_sp
1404 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1405 ldata_a => matrix_a(iz, ia) %local_data(1:nrows_local, 1:ncols_local)
1406 ldata_b => matrix_b(iz, ib) %matrix%local_data(1:nrows_local, 1:ncols_local)
1407 IF (use_accurate_sum)
THEN
1410 t = t + sum(ldata_a*ldata_b)
1412 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1413 ldata_a_sp => matrix_a(iz, ia) %local_data_sp(1:nrows_local, 1:ncols_local)
1414 ldata_b_sp => matrix_b(iz, ib) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1415 IF (use_accurate_sum)
THEN
1418 t = t + sum(ldata_a_sp*ldata_b_sp)
1421 cpabort(
"Matrices A and B are of different types")
1428 group = matrix_a(1, 1) %matrix_struct%para_env
1429 CALL group%sum(trace)
1431 CALL timestop(handle)
1432 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_ap
1433 SUBROUTINE cp_fm_contracted_trace_a2b2t2_pa (matrix_a, matrix_b, trace, accurate)
1434 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1435 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1436 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1437 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1439 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_pa'
1441 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1443 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1444 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1446 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1447 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1450 CALL timeset(routinen, handle)
1452 nz =
SIZE(matrix_a, 1)
1453 cpassert(
SIZE(matrix_b, 1) == nz)
1455 na =
SIZE(matrix_a, 2)
1456 nb =
SIZE(matrix_b, 2)
1457 cpassert(
SIZE(trace, 1) == na)
1458 cpassert(
SIZE(trace, 2) == nb)
1460 use_accurate_sum = .true.
1461 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1466 na8 = int(na, kind=
int_8)
1472 DO itrace = 1, ntraces
1473 ib8 = (itrace - 1)/na8
1474 ia = int(itrace - ib8*na8)
1479 CALL cp_fm_get_info(matrix_a(iz, ia) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1480 use_sp_a = matrix_a(iz, ia) %matrix%use_sp
1481 use_sp_b = matrix_b(iz, ib) %use_sp
1484 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1485 ldata_a => matrix_a(iz, ia) %matrix%local_data(1:nrows_local, 1:ncols_local)
1486 ldata_b => matrix_b(iz, ib) %local_data(1:nrows_local, 1:ncols_local)
1487 IF (use_accurate_sum)
THEN
1490 t = t + sum(ldata_a*ldata_b)
1492 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1493 ldata_a_sp => matrix_a(iz, ia) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1494 ldata_b_sp => matrix_b(iz, ib) %local_data_sp(1:nrows_local, 1:ncols_local)
1495 IF (use_accurate_sum)
THEN
1498 t = t + sum(ldata_a_sp*ldata_b_sp)
1501 cpabort(
"Matrices A and B are of different types")
1508 group = matrix_a(1, 1) %matrix%matrix_struct%para_env
1509 CALL group%sum(trace)
1511 CALL timestop(handle)
1512 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_pa
1513 SUBROUTINE cp_fm_contracted_trace_a2b2t2_pp (matrix_a, matrix_b, trace, accurate)
1514 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1515 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1516 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1517 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1519 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_pp'
1521 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1523 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1524 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1526 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1527 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1530 CALL timeset(routinen, handle)
1532 nz =
SIZE(matrix_a, 1)
1533 cpassert(
SIZE(matrix_b, 1) == nz)
1535 na =
SIZE(matrix_a, 2)
1536 nb =
SIZE(matrix_b, 2)
1537 cpassert(
SIZE(trace, 1) == na)
1538 cpassert(
SIZE(trace, 2) == nb)
1540 use_accurate_sum = .true.
1541 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1546 na8 = int(na, kind=
int_8)
1552 DO itrace = 1, ntraces
1553 ib8 = (itrace - 1)/na8
1554 ia = int(itrace - ib8*na8)
1559 CALL cp_fm_get_info(matrix_a(iz, ia) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1560 use_sp_a = matrix_a(iz, ia) %matrix%use_sp
1561 use_sp_b = matrix_b(iz, ib) %matrix%use_sp
1564 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1565 ldata_a => matrix_a(iz, ia) %matrix%local_data(1:nrows_local, 1:ncols_local)
1566 ldata_b => matrix_b(iz, ib) %matrix%local_data(1:nrows_local, 1:ncols_local)
1567 IF (use_accurate_sum)
THEN
1570 t = t + sum(ldata_a*ldata_b)
1572 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1573 ldata_a_sp => matrix_a(iz, ia) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1574 ldata_b_sp => matrix_b(iz, ib) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1575 IF (use_accurate_sum)
THEN
1578 t = t + sum(ldata_a_sp*ldata_b_sp)
1581 cpabort(
"Matrices A and B are of different types")
1588 group = matrix_a(1, 1) %matrix%matrix_struct%para_env
1589 CALL group%sum(trace)
1591 CALL timestop(handle)
1592 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_pp
1628 transpose_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, &
1630 TYPE(
cp_fm_type),
INTENT(IN) :: triangular_matrix, matrix_b
1631 CHARACTER,
INTENT(IN),
OPTIONAL :: side
1632 LOGICAL,
INTENT(IN),
OPTIONAL :: transpose_tr, invert_tr
1633 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo_tr
1634 LOGICAL,
INTENT(IN),
OPTIONAL :: unit_diag_tr
1635 INTEGER,
INTENT(IN),
OPTIONAL :: n_rows, n_cols
1636 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: alpha
1638 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_triangular_multiply'
1640 CHARACTER :: side_char, transa, unit_diag, uplo
1641 INTEGER :: handle, mdim, m, n
1645 CALL timeset(routinen, handle)
1653 IF (
PRESENT(side)) side_char = side
1654 mdim = merge(1, 2,
'L' == side_char)
1655 IF (
PRESENT(invert_tr)) invert = invert_tr
1656 IF (
PRESENT(uplo_tr)) uplo = uplo_tr
1657 IF (
PRESENT(unit_diag_tr))
THEN
1658 IF (unit_diag_tr)
THEN
1664 IF (
PRESENT(transpose_tr))
THEN
1665 IF (transpose_tr)
THEN
1671 IF (
PRESENT(alpha)) al = alpha
1672 IF (
PRESENT(n_rows)) m = n_rows
1673 IF (
PRESENT(n_cols)) n = n_cols
1677#if defined(__parallel)
1678 CALL pdtrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1679 triangular_matrix%local_data(1, 1), 1, 1, &
1680 triangular_matrix%matrix_struct%descriptor, &
1681 matrix_b%local_data(1, 1), 1, 1, &
1682 matrix_b%matrix_struct%descriptor(1))
1684 CALL dtrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1685 triangular_matrix%local_data(1, 1), &
1686 SIZE(triangular_matrix%local_data, mdim), &
1687 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1692#if defined(__parallel)
1693 CALL pdtrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1694 triangular_matrix%local_data(1, 1), 1, 1, &
1695 triangular_matrix%matrix_struct%descriptor, &
1696 matrix_b%local_data(1, 1), 1, 1, &
1697 matrix_b%matrix_struct%descriptor(1))
1699 CALL dtrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1700 triangular_matrix%local_data(1, 1), &
1701 SIZE(triangular_matrix%local_data, mdim), &
1702 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1707 CALL timestop(handle)
1719 REAL(kind=
dp),
INTENT(IN) :: alpha
1722 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_scale'
1724 INTEGER :: handle, size_a
1725 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1727 CALL timeset(routinen, handle)
1731 a => matrix_a%local_data
1732 size_a =
SIZE(a, 1)*
SIZE(a, 2)
1734 CALL dscal(size_a, alpha, a, 1)
1736 CALL timestop(handle)
1749 TYPE(
cp_fm_type),
INTENT(IN) :: matrix, matrixt
1751 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_transpose'
1753 INTEGER :: handle, ncol_global, &
1754 nrow_global, ncol_globalt, nrow_globalt
1755 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, c
1756#if defined(__parallel)
1757 INTEGER,
DIMENSION(9) :: desca, descc
1758#elif !defined(__MKL)
1762 nrow_global = matrix%matrix_struct%nrow_global
1763 ncol_global = matrix%matrix_struct%ncol_global
1764 nrow_globalt = matrixt%matrix_struct%nrow_global
1765 ncol_globalt = matrixt%matrix_struct%ncol_global
1766 cpassert(nrow_global == ncol_globalt)
1767 cpassert(nrow_globalt == ncol_global)
1769 CALL timeset(routinen, handle)
1771 a => matrix%local_data
1772 c => matrixt%local_data
1774#if defined(__parallel)
1775 desca(:) = matrix%matrix_struct%descriptor(:)
1776 descc(:) = matrixt%matrix_struct%descriptor(:)
1777 CALL pdtran(ncol_global, nrow_global, 1.0_dp, a(1, 1), 1, 1, desca, 0.0_dp, c(1, 1), 1, 1, descc)
1779 CALL mkl_domatcopy(
'C',
'T', nrow_global, ncol_global, 1.0_dp, a(1, 1), nrow_global, c(1, 1), ncol_global)
1781 DO j = 1, ncol_global
1782 DO i = 1, nrow_global
1787 CALL timestop(handle)
1803 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
1805 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_uplo_to_full'
1808 INTEGER :: handle, icol_global, irow_global, &
1809 mypcol, myprow, ncol_global, &
1811 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1812 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
1815#if defined(__parallel)
1816 INTEGER :: icol_local, irow_local, &
1817 ncol_block, ncol_local, &
1818 nrow_block, nrow_local
1819 INTEGER,
DIMENSION(9) :: desca, descc
1820 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: c
1821 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: c_sp
1825 IF (
PRESENT(uplo)) myuplo = uplo
1827 nrow_global = matrix%matrix_struct%nrow_global
1828 ncol_global = matrix%matrix_struct%ncol_global
1829 cpassert(nrow_global == ncol_global)
1830 nrow_global = work%matrix_struct%nrow_global
1831 ncol_global = work%matrix_struct%ncol_global
1832 cpassert(nrow_global == ncol_global)
1833 cpassert(matrix%use_sp .EQV. work%use_sp)
1835 CALL timeset(routinen, handle)
1837 context => matrix%matrix_struct%context
1838 myprow = context%mepos(1)
1839 mypcol = context%mepos(2)
1841#if defined(__parallel)
1843 nrow_block = matrix%matrix_struct%nrow_block
1844 ncol_block = matrix%matrix_struct%ncol_block
1846 nrow_local = matrix%matrix_struct%nrow_locals(myprow)
1847 ncol_local = matrix%matrix_struct%ncol_locals(mypcol)
1849 a => work%local_data
1850 a_sp => work%local_data_sp
1851 desca(:) = work%matrix_struct%descriptor(:)
1852 c => matrix%local_data
1853 c_sp => matrix%local_data_sp
1854 descc(:) = matrix%matrix_struct%descriptor(:)
1856 DO icol_local = 1, ncol_local
1857 icol_global = matrix%matrix_struct%col_indices(icol_local)
1858 DO irow_local = 1, nrow_local
1859 irow_global = matrix%matrix_struct%row_indices(irow_local)
1860 IF (merge(irow_global > icol_global, irow_global < icol_global, (myuplo ==
"U") .OR. (myuplo ==
"u")))
THEN
1861 IF (matrix%use_sp)
THEN
1862 c_sp(irow_local, icol_local) = 0.0_sp
1864 c(irow_local, icol_local) = 0.0_dp
1866 ELSE IF (irow_global == icol_global)
THEN
1867 IF (matrix%use_sp)
THEN
1868 c_sp(irow_local, icol_local) = 0.5_sp*c_sp(irow_local, icol_local)
1870 c(irow_local, icol_local) = 0.5_dp*c(irow_local, icol_local)
1876 DO icol_local = 1, ncol_local
1877 DO irow_local = 1, nrow_local
1878 IF (matrix%use_sp)
THEN
1879 a_sp(irow_local, icol_local) = c_sp(irow_local, icol_local)
1881 a(irow_local, icol_local) = c(irow_local, icol_local)
1886 IF (matrix%use_sp)
THEN
1887 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)
1889 CALL pdtran(nrow_global, ncol_global, 1.0_dp, a(1, 1), 1, 1, desca, 1.0_dp, c(1, 1), 1, 1, descc)
1894 a => matrix%local_data
1895 a_sp => matrix%local_data_sp
1897 IF ((myuplo ==
"U") .OR. (myuplo ==
"u"))
THEN
1898 DO irow_global = 1, nrow_global
1899 DO icol_global = irow_global + 1, ncol_global
1900 IF (matrix%use_sp)
THEN
1901 a_sp(icol_global, irow_global) = a_sp(irow_global, icol_global)
1903 a(icol_global, irow_global) = a(irow_global, icol_global)
1908 DO icol_global = 1, ncol_global
1909 DO irow_global = icol_global + 1, nrow_global
1910 IF (matrix%use_sp)
THEN
1911 a_sp(irow_global, icol_global) = a_sp(icol_global, irow_global)
1913 a(irow_global, icol_global) = a(icol_global, irow_global)
1920 CALL timestop(handle)
1938 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: scaling
1940 INTEGER :: k, mypcol, myprow, n, ncol_global, &
1942 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1943 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
1944#if defined(__parallel)
1945 INTEGER :: icol_global, icol_local, &
1946 ipcol, iprow, irow_local
1951 myprow = matrixa%matrix_struct%context%mepos(1)
1952 mypcol = matrixa%matrix_struct%context%mepos(2)
1953 nprow = matrixa%matrix_struct%context%num_pe(1)
1954 npcol = matrixa%matrix_struct%context%num_pe(2)
1956 ncol_global = matrixa%matrix_struct%ncol_global
1958 a => matrixa%local_data
1959 a_sp => matrixa%local_data_sp
1960 IF (matrixa%use_sp)
THEN
1965 k = min(
SIZE(scaling), ncol_global)
1967#if defined(__parallel)
1969 DO icol_global = 1, k
1970 CALL infog2l(1, icol_global, matrixa%matrix_struct%descriptor, &
1971 nprow, npcol, myprow, mypcol, &
1972 irow_local, icol_local, iprow, ipcol)
1973 IF ((ipcol == mypcol))
THEN
1974 IF (matrixa%use_sp)
THEN
1975 CALL sscal(n, real(scaling(icol_global),
sp), a_sp(:, icol_local), 1)
1977 CALL dscal(n, scaling(icol_global), a(:, icol_local), 1)
1983 IF (matrixa%use_sp)
THEN
1984 CALL sscal(n, real(scaling(i),
sp), a_sp(:, i), 1)
1986 CALL dscal(n, scaling(i), a(:, i), 1)
2001 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: scaling
2003 INTEGER :: n, m, nrow_global, nrow_local, ncol_local
2004 INTEGER,
DIMENSION(:),
POINTER :: row_indices
2005 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2006 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
2007#if defined(__parallel)
2008 INTEGER :: irow_global, icol, irow
2013 CALL cp_fm_get_info(matrixa, row_indices=row_indices, nrow_global=nrow_global, &
2014 nrow_local=nrow_local, ncol_local=ncol_local)
2015 cpassert(
SIZE(scaling) == nrow_global)
2017 a => matrixa%local_data
2018 a_sp => matrixa%local_data_sp
2019 IF (matrixa%use_sp)
THEN
2027#if defined(__parallel)
2028 DO icol = 1, ncol_local
2029 IF (matrixa%use_sp)
THEN
2030 DO irow = 1, nrow_local
2031 irow_global = row_indices(irow)
2032 a(irow, icol) = real(scaling(irow_global),
dp)*a(irow, icol)
2035 DO irow = 1, nrow_local
2036 irow_global = row_indices(irow)
2037 a(irow, icol) = scaling(irow_global)*a(irow, icol)
2042 IF (matrixa%use_sp)
THEN
2044 a_sp(1:n, j) = real(scaling(1:n),
sp)*a_sp(1:n, j)
2048 a(1:n, j) = scaling(1:n)*a(1:n, j)
2072 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_inverse
2073 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: det_a
2074 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_svd
2075 REAL(kind=
dp),
DIMENSION(:),
POINTER, &
2076 INTENT(INOUT),
OPTIONAL :: eigval
2079 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
2080 REAL(kind=
dp) :: determinant, my_eps_svd
2081 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2084#if defined(__parallel)
2085 TYPE(
cp_fm_type) :: u, vt, sigma, inv_sigma_ut
2087 INTEGER :: i, info, liwork, lwork, exponent_of_minus_one
2088 INTEGER,
DIMENSION(9) :: desca
2090 REAL(kind=
dp) :: alpha, beta
2091 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
diag
2092 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
2095 REAL(kind=
dp) :: eps1
2099 IF (
PRESENT(eps_svd)) my_eps_svd = eps_svd
2102 matrix_struct=matrix_a%matrix_struct, &
2106 a => matrix_lu%local_data
2107 n = matrix_lu%matrix_struct%nrow_global
2108 ALLOCATE (ipivot(n + matrix_a%matrix_struct%nrow_block))
2110#if defined(__parallel)
2111 IF (my_eps_svd == 0.0_dp)
THEN
2115 desca(:) = matrix_lu%matrix_struct%descriptor(:)
2116 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
2118 IF (
PRESENT(det_a) .OR.
PRESENT(eigval))
THEN
2124 exponent_of_minus_one = 0
2125 determinant = 1.0_dp
2127 determinant = determinant*
diag(i)
2128 IF (ipivot(i) /= i)
THEN
2129 exponent_of_minus_one = exponent_of_minus_one + 1
2132 IF (
PRESENT(eigval))
THEN
2133 cpassert(.NOT.
ASSOCIATED(eigval))
2134 ALLOCATE (eigval(n))
2139 group = matrix_lu%matrix_struct%para_env
2140 CALL group%sum(exponent_of_minus_one)
2142 determinant = determinant*(-1.0_dp)**exponent_of_minus_one
2149 CALL pdgetrs(
'N', n, n, matrix_lu%local_data, 1, 1, desca, ipivot, matrix_inverse%local_data, 1, 1, desca, info)
2153 matrix_struct=matrix_a%matrix_struct, &
2154 name=
"LEFT_SINGULAR_MATRIX")
2157 matrix_struct=matrix_a%matrix_struct, &
2158 name=
"RIGHT_SINGULAR_MATRIX")
2162 desca(:) = matrix_lu%matrix_struct%descriptor(:)
2166 CALL pdgesvd(
'V',
'V', n, n, matrix_lu%local_data, 1, 1, desca,
diag, u%local_data, &
2167 1, 1, desca, vt%local_data, 1, 1, desca, work, lwork, info)
2168 lwork = int(work(1))
2170 ALLOCATE (work(lwork))
2172 CALL pdgesvd(
'V',
'V', n, n, matrix_lu%local_data, 1, 1, desca,
diag, u%local_data, &
2173 1, 1, desca, vt%local_data, 1, 1, desca, work, lwork, info)
2176 IF (info /= 0 .AND. info /= n + 1) &
2177 cpabort(
"Singular value decomposition of matrix failed.")
2180 matrix_struct=matrix_a%matrix_struct, &
2181 name=
"SINGULAR_VALUE_MATRIX")
2183 determinant = 1.0_dp
2185 IF (
PRESENT(eigval))
THEN
2186 cpassert(.NOT.
ASSOCIATED(eigval))
2187 ALLOCATE (eigval(n))
2191 IF (
diag(i) < my_eps_svd)
THEN
2195 determinant = determinant*
diag(i)
2202 CALL cp_warn(__location__, &
2203 "Linear dependencies were detected in the SVD inversion of matrix "//trim(adjustl(matrix_a%name))// &
2204 ". At least one singular value has been quenched.")
2207 matrix_struct=matrix_a%matrix_struct, &
2208 name=
"SINGULAR_VALUE_MATRIX")
2210 CALL pdgemm(
'N',
'T', n, n, n, 1.0_dp, sigma%local_data, 1, 1, desca, &
2211 u%local_data, 1, 1, desca, 0.0_dp, inv_sigma_ut%local_data, 1, 1, desca)
2214 CALL pdgemm(
'T',
'N', n, n, n, 1.0_dp, vt%local_data, 1, 1, desca, &
2215 inv_sigma_ut%local_data, 1, 1, desca, 0.0_dp, matrix_inverse%local_data, 1, 1, desca)
2224 IF (my_eps_svd == 0.0_dp)
THEN
2226 CALL invert_matrix(matrix_a%local_data, matrix_inverse%local_data, &
2228 CALL cp_fm_lu_decompose(matrix_lu, determinant, correct_sign=sign)
2229 IF (
PRESENT(eigval)) &
2230 CALL cp_abort(__location__, &
2231 "NYI. Eigenvalues not available for return without SCALAPACK.")
2234 determinant, eigval)
2239 IF (
PRESENT(det_a)) det_a = determinant
2251 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo_tr
2253 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_triangular_invert'
2255 CHARACTER :: unit_diag, uplo
2256 INTEGER :: handle, info, ncol_global
2257 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2258#if defined(__parallel)
2259 INTEGER,
DIMENSION(9) :: desca
2262 CALL timeset(routinen, handle)
2266 IF (
PRESENT(uplo_tr)) uplo = uplo_tr
2268 ncol_global = matrix_a%matrix_struct%ncol_global
2270 a => matrix_a%local_data
2272#if defined(__parallel)
2273 desca(:) = matrix_a%matrix_struct%descriptor(:)
2275 CALL pdtrtri(uplo, unit_diag, ncol_global, a(1, 1), 1, 1, desca, info)
2278 CALL dtrtri(uplo, unit_diag, ncol_global, a(1, 1), ncol_global, info)
2281 CALL timestop(handle)
2297 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_r
2298 INTEGER,
INTENT(IN),
OPTIONAL :: nrow_fact, ncol_fact, &
2299 first_row, first_col
2300 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
2302 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_qr_factorization'
2305 INTEGER :: handle, i, icol, info, irow, &
2306 j, lda, lwork, ncol, &
2308 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tau, work
2309 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: r_mat
2310 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2311#if defined(__parallel)
2312 INTEGER,
DIMENSION(9) :: desca
2315 CALL timeset(routinen, handle)
2318 IF (
PRESENT(uplo)) myuplo = uplo
2320 ncol = matrix_a%matrix_struct%ncol_global
2321 nrow = matrix_a%matrix_struct%nrow_global
2324 a => matrix_a%local_data
2326 IF (
PRESENT(nrow_fact)) nrow = nrow_fact
2327 IF (
PRESENT(ncol_fact)) ncol = ncol_fact
2329 IF (
PRESENT(first_row)) irow = first_row
2331 IF (
PRESENT(first_col)) icol = first_col
2333 cpassert(nrow >= ncol)
2335 ALLOCATE (tau(ndim))
2337#if defined(__parallel)
2339 desca(:) = matrix_a%matrix_struct%descriptor(:)
2342 ALLOCATE (work(2*ndim))
2343 CALL pdgeqrf(nrow, ncol, a, irow, icol, desca, tau, work, lwork, info)
2344 lwork = int(work(1))
2346 ALLOCATE (work(lwork))
2347 CALL pdgeqrf(nrow, ncol, a, irow, icol, desca, tau, work, lwork, info)
2351 ALLOCATE (work(2*ndim))
2352 CALL dgeqrf(nrow, ncol, a, lda, tau, work, lwork, info)
2353 lwork = int(work(1))
2355 ALLOCATE (work(lwork))
2356 CALL dgeqrf(nrow, ncol, a, lda, tau, work, lwork, info)
2360 ALLOCATE (r_mat(ncol, ncol))
2362 IF ((myuplo ==
"U") .OR. (myuplo ==
"u"))
THEN
2365 r_mat(j, i) = 0.0_dp
2371 r_mat(i, j) = 0.0_dp
2377 DEALLOCATE (tau, work, r_mat)
2379 CALL timestop(handle)
2390 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, general_a
2392 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_solve'
2394 INTEGER :: handle, info, n, nrhs
2395 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
2396 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, a_general
2397#if defined(__parallel)
2398 INTEGER,
DIMENSION(9) :: desca, descb
2403 CALL timeset(routinen, handle)
2405 a => matrix_a%local_data
2406 a_general => general_a%local_data
2407 n = matrix_a%matrix_struct%nrow_global
2408 nrhs = general_a%matrix_struct%ncol_global
2409 ALLOCATE (ipivot(n + matrix_a%matrix_struct%nrow_block))
2411#if defined(__parallel)
2412 desca(:) = matrix_a%matrix_struct%descriptor(:)
2413 descb(:) = general_a%matrix_struct%descriptor(:)
2414 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
2415 CALL pdgetrs(
"N", n, nrhs, a, 1, 1, desca, ipivot, a_general, &
2420 ldb =
SIZE(a_general, 1)
2421 CALL dgetrf(n, n, a, lda, ipivot, info)
2422 CALL dgetrs(
"N", n, nrhs, a, lda, ipivot, a_general, ldb, info)
2428 CALL timestop(handle)
2459 SUBROUTINE cp_complex_fm_gemm(transa, transb, m, n, k, alpha, A_re, A_im, B_re, B_im, beta, &
2460 C_re, C_im, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, &
2462 CHARACTER(LEN=1),
INTENT(IN) :: transa, transb
2463 INTEGER,
INTENT(IN) :: m, n, k
2464 REAL(kind=
dp),
INTENT(IN) :: alpha
2465 TYPE(
cp_fm_type),
INTENT(IN) :: a_re, a_im, b_re, b_im
2466 REAL(kind=
dp),
INTENT(IN) :: beta
2468 INTEGER,
INTENT(IN),
OPTIONAL :: a_first_col, a_first_row, b_first_col, &
2469 b_first_row, c_first_col, c_first_row
2471 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_complex_fm_gemm'
2475 CALL timeset(routinen, handle)
2477 CALL cp_fm_gemm(transa, transb, m, n, k, alpha, a_re, b_re, beta, c_re, &
2478 a_first_col=a_first_col, &
2479 a_first_row=a_first_row, &
2480 b_first_col=b_first_col, &
2481 b_first_row=b_first_row, &
2482 c_first_col=c_first_col, &
2483 c_first_row=c_first_row)
2484 CALL cp_fm_gemm(transa, transb, m, n, k, -alpha, a_im, b_im, 1.0_dp, c_re, &
2485 a_first_col=a_first_col, &
2486 a_first_row=a_first_row, &
2487 b_first_col=b_first_col, &
2488 b_first_row=b_first_row, &
2489 c_first_col=c_first_col, &
2490 c_first_row=c_first_row)
2491 CALL cp_fm_gemm(transa, transb, m, n, k, alpha, a_re, b_im, beta, c_im, &
2492 a_first_col=a_first_col, &
2493 a_first_row=a_first_row, &
2494 b_first_col=b_first_col, &
2495 b_first_row=b_first_row, &
2496 c_first_col=c_first_col, &
2497 c_first_row=c_first_row)
2498 CALL cp_fm_gemm(transa, transb, m, n, k, alpha, a_im, b_re, 1.0_dp, c_im, &
2499 a_first_col=a_first_col, &
2500 a_first_row=a_first_row, &
2501 b_first_col=b_first_col, &
2502 b_first_row=b_first_row, &
2503 c_first_col=c_first_col, &
2504 c_first_row=c_first_row)
2506 CALL timestop(handle)
2517 SUBROUTINE cp_fm_lu_invert(matrix, info_out)
2519 INTEGER,
INTENT(OUT),
OPTIONAL :: info_out
2521 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_lu_invert'
2523 INTEGER :: nrows_global, handle, info, lwork
2524 INTEGER,
DIMENSION(:),
ALLOCATABLE :: ipivot
2525 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: mat
2526 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: mat_sp
2527 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: work
2528 REAL(kind=
sp),
DIMENSION(:),
ALLOCATABLE :: work_sp
2529#if defined(__parallel)
2531 INTEGER,
DIMENSION(9) :: desca
2532 INTEGER,
DIMENSION(:),
ALLOCATABLE :: iwork
2537 CALL timeset(routinen, handle)
2539 mat => matrix%local_data
2540 mat_sp => matrix%local_data_sp
2541 nrows_global = matrix%matrix_struct%nrow_global
2542 cpassert(nrows_global == matrix%matrix_struct%ncol_global)
2543 ALLOCATE (ipivot(nrows_global))
2545#if defined(__parallel)
2546 desca = matrix%matrix_struct%descriptor
2547 IF (matrix%use_sp)
THEN
2548 CALL psgetrf(nrows_global, nrows_global, &
2549 mat_sp, 1, 1, desca, ipivot, info)
2551 CALL pdgetrf(nrows_global, nrows_global, &
2552 mat, 1, 1, desca, ipivot, info)
2556 IF (matrix%use_sp)
THEN
2557 CALL sgetrf(nrows_global, nrows_global, &
2558 mat_sp, lda, ipivot, info)
2560 CALL dgetrf(nrows_global, nrows_global, &
2561 mat, lda, ipivot, info)
2565 CALL cp_abort(__location__,
"LU decomposition has failed")
2568 IF (matrix%use_sp)
THEN
2571 ALLOCATE (work_sp(1))
2573#if defined(__parallel)
2575 IF (matrix%use_sp)
THEN
2576 CALL psgetri(nrows_global, mat_sp, 1, 1, desca, &
2577 ipivot, work_sp, -1, iwork, -1, info)
2578 lwork = int(work_sp(1))
2579 DEALLOCATE (work_sp)
2580 ALLOCATE (work_sp(lwork))
2582 CALL pdgetri(nrows_global, mat, 1, 1, desca, &
2583 ipivot, work, -1, iwork, -1, info)
2584 lwork = int(work(1))
2586 ALLOCATE (work(lwork))
2588 liwork = int(iwork(1))
2590 ALLOCATE (iwork(liwork))
2591 IF (matrix%use_sp)
THEN
2592 CALL psgetri(nrows_global, mat_sp, 1, 1, desca, &
2593 ipivot, work_sp, lwork, iwork, liwork, info)
2595 CALL pdgetri(nrows_global, mat, 1, 1, desca, &
2596 ipivot, work, lwork, iwork, liwork, info)
2600 IF (matrix%use_sp)
THEN
2601 CALL sgetri(nrows_global, mat_sp, lda, &
2602 ipivot, work_sp, -1, info)
2603 lwork = int(work_sp(1))
2604 DEALLOCATE (work_sp)
2605 ALLOCATE (work_sp(lwork))
2606 CALL sgetri(nrows_global, mat_sp, lda, &
2607 ipivot, work_sp, lwork, info)
2609 CALL dgetri(nrows_global, mat, lda, &
2610 ipivot, work, -1, info)
2611 lwork = int(work(1))
2613 ALLOCATE (work(lwork))
2614 CALL dgetri(nrows_global, mat, lda, &
2615 ipivot, work, lwork, info)
2618 IF (matrix%use_sp)
THEN
2619 DEALLOCATE (work_sp)
2625 IF (
PRESENT(info_out))
THEN
2629 CALL cp_abort(__location__,
"LU inversion has failed")
2632 CALL timestop(handle)
2634 END SUBROUTINE cp_fm_lu_invert
2648 CHARACTER,
INTENT(IN) :: mode
2649 REAL(kind=
dp) :: res
2651 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_norm'
2653 INTEGER :: nrows, ncols, handle, lwork, nrows_local, ncols_local
2654 REAL(kind=
sp) :: res_sp
2655 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: aa
2656 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: aa_sp
2657 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: work
2658 REAL(kind=
sp),
DIMENSION(:),
ALLOCATABLE :: work_sp
2659#if defined(__parallel)
2660 INTEGER,
DIMENSION(9) :: desca
2665 CALL timeset(routinen, handle)
2668 nrow_global=nrows, &
2669 ncol_global=ncols, &
2670 nrow_local=nrows_local, &
2671 ncol_local=ncols_local)
2672 aa => matrix%local_data
2673 aa_sp => matrix%local_data_sp
2675#if defined(__parallel)
2676 desca = matrix%matrix_struct%descriptor
2680 CASE (
'1',
'O',
'o')
2684 CASE (
'F',
'f',
'E',
'e')
2687 cpabort(
"mode input is not valid")
2689 IF (matrix%use_sp)
THEN
2690 ALLOCATE (work_sp(lwork))
2691 res_sp = pslange(mode, nrows, ncols, aa_sp, 1, 1, desca, work_sp)
2692 DEALLOCATE (work_sp)
2693 res = real(res_sp, kind=
dp)
2695 ALLOCATE (work(lwork))
2696 res = pdlange(mode, nrows, ncols, aa, 1, 1, desca, work)
2703 CASE (
'1',
'O',
'o')
2707 CASE (
'F',
'f',
'E',
'e')
2710 cpabort(
"mode input is not valid")
2712 IF (matrix%use_sp)
THEN
2713 ALLOCATE (work_sp(lwork))
2714 lda =
SIZE(aa_sp, 1)
2715 res_sp = slange(mode, nrows, ncols, aa_sp, lda, work_sp)
2716 DEALLOCATE (work_sp)
2717 res = real(res_sp, kind=
dp)
2719 ALLOCATE (work(lwork))
2721 res = dlange(mode, nrows, ncols, aa, lda, work)
2726 CALL timestop(handle)
2736 FUNCTION cp_fm_latra(matrix)
RESULT(res)
2738 REAL(kind=
dp) :: res
2740 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_latra'
2742 INTEGER :: nrows, ncols, handle
2743 REAL(kind=
sp) :: res_sp
2744 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: aa
2745 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: aa_sp
2746#if defined(__parallel)
2747 INTEGER,
DIMENSION(9) :: desca
2752 CALL timeset(routinen, handle)
2754 nrows = matrix%matrix_struct%nrow_global
2755 ncols = matrix%matrix_struct%ncol_global
2756 cpassert(nrows == ncols)
2757 aa => matrix%local_data
2758 aa_sp => matrix%local_data_sp
2760#if defined(__parallel)
2761 desca = matrix%matrix_struct%descriptor
2762 IF (matrix%use_sp)
THEN
2763 res_sp = pslatra(nrows, aa_sp, 1, 1, desca)
2764 res = real(res_sp, kind=
dp)
2766 res = pdlatra(nrows, aa, 1, 1, desca)
2769 IF (matrix%use_sp)
THEN
2772 res_sp = res_sp + aa_sp(ii, ii)
2774 res = real(res_sp, kind=
dp)
2778 res = res + aa(ii, ii)
2783 CALL timestop(handle)
2785 END FUNCTION cp_fm_latra
2801 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tau
2802 INTEGER,
INTENT(IN) :: nrow, ncol, first_row, first_col
2804 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_pdgeqpf'
2807 INTEGER :: info, lwork
2808 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipiv
2809 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2810 REAL(kind=
dp),
DIMENSION(:),
POINTER :: work
2811#if defined(__parallel)
2812 INTEGER,
DIMENSION(9) :: descc
2817 CALL timeset(routinen, handle)
2819 a => matrix%local_data
2821 ALLOCATE (work(2*nrow))
2822 ALLOCATE (ipiv(ncol))
2825#if defined(__parallel)
2826 descc(:) = matrix%matrix_struct%descriptor(:)
2828 CALL pdgeqpf(nrow, ncol, a, first_row, first_col, descc, ipiv, tau, work, lwork, info)
2829 lwork = int(work(1))
2831 ALLOCATE (work(lwork))
2836 CALL pdgeqpf(nrow, ncol, a, first_row, first_col, descc, ipiv, tau, work, lwork, info)
2838 cpassert(first_row == 1 .AND. first_col == 1)
2840 CALL dgeqp3(nrow, ncol, a, lda, ipiv, tau, work, lwork, info)
2841 lwork = int(work(1))
2843 ALLOCATE (work(lwork))
2846 CALL dgeqp3(nrow, ncol, a, lda, ipiv, tau, work, lwork, info)
2853 CALL timestop(handle)
2873 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tau
2874 INTEGER,
INTENT(IN) :: nrow, first_row, first_col
2876 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_pdorgqr'
2879 INTEGER :: info, lwork
2880 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2881 REAL(kind=
dp),
DIMENSION(:),
POINTER :: work
2882#if defined(__parallel)
2883 INTEGER,
DIMENSION(9) :: descc
2888 CALL timeset(routinen, handle)
2890 a => matrix%local_data
2892 ALLOCATE (work(2*nrow))
2895#if defined(__parallel)
2896 descc(:) = matrix%matrix_struct%descriptor(:)
2898 CALL pdorgqr(nrow, nrow, nrow, a, first_row, first_col, descc, tau, work, lwork, info)
2900 lwork = int(work(1))
2902 ALLOCATE (work(lwork))
2905 CALL pdorgqr(nrow, nrow, nrow, a, first_row, first_col, descc, tau, work, lwork, info)
2907 cpassert(first_row == 1 .AND. first_col == 1)
2909 CALL dorgqr(nrow, nrow, nrow, a, lda, tau, work, lwork, info)
2910 lwork = int(work(1))
2912 ALLOCATE (work(lwork))
2913 CALL dorgqr(nrow, nrow, nrow, a, lda, tau, work, lwork, info)
2918 CALL timestop(handle)
2933 INTEGER,
INTENT(IN) :: irow, jrow
2934 REAL(
dp),
INTENT(IN) :: cs, sn
2936 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_rot_rows'
2937 INTEGER :: handle, ncol
2939#if defined(__parallel)
2940 INTEGER :: info, lwork
2941 INTEGER,
DIMENSION(9) :: desc
2942 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
2944 CALL timeset(routinen, handle)
2946#if defined(__parallel)
2947 IF (1 /= matrix%matrix_struct%context%n_pid)
THEN
2949 ALLOCATE (work(lwork))
2950 desc(:) = matrix%matrix_struct%descriptor(:)
2952 matrix%local_data(1, 1), irow, 1, desc, ncol, &
2953 matrix%local_data(1, 1), jrow, 1, desc, ncol, &
2954 cs, sn, work, lwork, info)
2959 CALL drot(ncol, matrix%local_data(irow, 1), ncol, matrix%local_data(jrow, 1), ncol, cs, sn)
2960#if defined(__parallel)
2963 CALL timestop(handle)
2977 INTEGER,
INTENT(IN) :: icol, jcol
2978 REAL(
dp),
INTENT(IN) :: cs, sn
2980 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_rot_cols'
2981 INTEGER :: handle, nrow
2983#if defined(__parallel)
2984 INTEGER :: info, lwork
2985 INTEGER,
DIMENSION(9) :: desc
2986 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
2988 CALL timeset(routinen, handle)
2990#if defined(__parallel)
2991 IF (1 /= matrix%matrix_struct%context%n_pid)
THEN
2993 ALLOCATE (work(lwork))
2994 desc(:) = matrix%matrix_struct%descriptor(:)
2996 matrix%local_data(1, 1), 1, icol, desc, 1, &
2997 matrix%local_data(1, 1), 1, jcol, desc, 1, &
2998 cs, sn, work, lwork, info)
3003 CALL drot(nrow, matrix%local_data(1, icol), 1, matrix%local_data(1, jcol), 1, cs, sn)
3004#if defined(__parallel)
3007 CALL timestop(handle)
3025 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: b
3026 INTEGER,
INTENT(IN),
OPTIONAL :: nrows, ncols, start_row, start_col
3027 LOGICAL,
INTENT(IN),
OPTIONAL :: do_norm, do_print
3029 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_Gram_Schmidt_orthonorm'
3031 INTEGER :: end_col_global, end_col_local, end_row_global, end_row_local, handle, i, j, &
3032 j_col, ncol_global, ncol_local, nrow_global, nrow_local, start_col_global, &
3033 start_col_local, start_row_global, start_row_local, this_col, unit_nr
3034 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
3035 LOGICAL :: my_do_norm, my_do_print
3036 REAL(kind=
dp) :: norm
3037 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
3039 CALL timeset(routinen, handle)
3042 IF (
PRESENT(do_norm)) my_do_norm = do_norm
3044 my_do_print = .false.
3045 IF (
PRESENT(do_print) .AND. (my_do_norm)) my_do_print = do_print
3048 IF (my_do_print)
THEN
3050 IF (unit_nr < 1) my_do_print = .false.
3053 IF (
SIZE(b) /= 0)
THEN
3054 IF (
PRESENT(nrows))
THEN
3057 nrow_global =
SIZE(b, 1)
3060 IF (
PRESENT(ncols))
THEN
3063 ncol_global =
SIZE(b, 2)
3066 IF (
PRESENT(start_row))
THEN
3067 start_row_global = start_row
3069 start_row_global = 1
3072 IF (
PRESENT(start_col))
THEN
3073 start_col_global = start_col
3075 start_col_global = 1
3078 end_row_global = start_row_global + nrow_global - 1
3079 end_col_global = start_col_global + ncol_global - 1
3082 nrow_global=nrow_global, ncol_global=ncol_global, &
3083 nrow_local=nrow_local, ncol_local=ncol_local, &
3084 row_indices=row_indices, col_indices=col_indices)
3085 IF (end_row_global > nrow_global)
THEN
3086 end_row_global = nrow_global
3088 IF (end_col_global > ncol_global)
THEN
3089 end_col_global = ncol_global
3096 DO start_row_local = 1, nrow_local
3097 IF (row_indices(start_row_local) >= start_row_global)
EXIT
3100 DO end_row_local = start_row_local, nrow_local
3101 IF (row_indices(end_row_local) > end_row_global)
EXIT
3103 end_row_local = end_row_local - 1
3105 DO start_col_local = 1, ncol_local
3106 IF (col_indices(start_col_local) >= start_col_global)
EXIT
3109 DO end_col_local = start_col_local, ncol_local
3110 IF (col_indices(end_col_local) > end_col_global)
EXIT
3112 end_col_local = end_col_local - 1
3114 a => matrix_a%local_data
3116 this_col = col_indices(start_col_local) - start_col_global + 1
3118 b(:, this_col) = a(:, start_col_local)
3120 IF (my_do_norm)
THEN
3122 b(:, this_col) = b(:, this_col)/norm
3123 IF (my_do_print)
WRITE (unit_nr,
'(I3,F8.3)') this_col, norm
3126 DO i = start_col_local + 1, end_col_local
3127 this_col = col_indices(i) - start_col_global + 1
3128 b(:, this_col) = a(:, i)
3129 DO j = start_col_local, i - 1
3130 j_col = col_indices(j) - start_col_global + 1
3131 b(:, this_col) = b(:, this_col) - &
3136 IF (my_do_norm)
THEN
3138 b(:, this_col) = b(:, this_col)/norm
3139 IF (my_do_print)
WRITE (unit_nr,
'(I3,F8.3)') this_col, norm
3143 CALL matrix_a%matrix_struct%para_env%sum(b)
3146 CALL timestop(handle)
3158 INTEGER,
INTENT(IN) :: n
3159 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
3163 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
3164 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
3165#if defined(__parallel)
3166 INTEGER,
DIMENSION(9) :: desca
3170 IF (
PRESENT(uplo)) myuplo = uplo
3172 a => fm_matrix%local_data
3173 a_sp => fm_matrix%local_data_sp
3174#if defined(__parallel)
3175 desca(:) = fm_matrix%matrix_struct%descriptor(:)
3176 IF (fm_matrix%use_sp)
THEN
3177 CALL pspotrf(myuplo, n, a_sp(1, 1), 1, 1, desca, info)
3179 CALL pdpotrf(myuplo, n, a(1, 1), 1, 1, desca, info)
3182 IF (fm_matrix%use_sp)
THEN
3183 CALL spotrf(myuplo, n, a_sp(1, 1),
SIZE(a_sp, 1), info)
3185 CALL dpotrf(myuplo, n, a(1, 1),
SIZE(a, 1), info)
3189 cpabort(
"Cholesky decomposition failed. Matrix ill-conditioned?")
3201 INTEGER,
INTENT(IN) :: n
3202 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
3205 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
3206 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
3208#if defined(__parallel)
3209 INTEGER,
DIMENSION(9) :: desca
3213 IF (
PRESENT(uplo)) myuplo = uplo
3215 a => fm_matrix%local_data
3216 a_sp => fm_matrix%local_data_sp
3217#if defined(__parallel)
3218 desca(:) = fm_matrix%matrix_struct%descriptor(:)
3219 IF (fm_matrix%use_sp)
THEN
3220 CALL pspotri(myuplo, n, a_sp(1, 1), 1, 1, desca, info)
3222 CALL pdpotri(myuplo, n, a(1, 1), 1, 1, desca, info)
3225 IF (fm_matrix%use_sp)
THEN
3226 CALL spotri(myuplo, n, a_sp(1, 1),
SIZE(a_sp, 1), info)
3228 CALL dpotri(myuplo, n, a(1, 1),
SIZE(a, 1), info)
3244 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: xv
3245 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: yv
3246 REAL(kind=
dp),
OPTIONAL,
INTENT(IN) :: alpha, beta
3248 INTEGER :: na, nc, nx, ny
3249 REAL(kind=
dp) :: aval, bval
3250#if defined(__parallel)
3251 INTEGER :: nrl, ncl, ic, ir
3252 INTEGER,
DIMENSION(:),
POINTER :: rind, cind
3253 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: xvl, yvl, yvm
3256 IF (amat%use_sp)
THEN
3257 cpabort(
"cp_fm_matvec: SP option not available")
3260 IF (
PRESENT(alpha)) aval = alpha
3262 IF (
PRESENT(beta)) bval = beta
3267 IF ((nx /= ny) .OR. (nc /= nx))
THEN
3268 cpabort(
"cp_fm_matvec: incompatible dimensions")
3270#if defined(__parallel)
3272 row_indices=rind, col_indices=cind)
3273 ALLOCATE (xvl(ncl), yvl(nrl), yvm(ny))
3275 xvl(ic) = xv(cind(ic))
3277 yvl(1:nrl) = matmul(amat%local_data, xvl(1:ncl))
3280 yvm(rind(ir)) = yvl(ir)
3282 CALL amat%matrix_struct%para_env%sum(yvm)
3283 IF (bval == 0.0_dp)
THEN
3286 yv = bval*yv + aval*yvm
3289 IF (bval == 0.0_dp)
THEN
3290 yv = aval*matmul(amat%local_data, xv)
3292 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