32#include "../base/base_uses.f90"
37 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
38 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_fm_basic_linalg'
71 REAL(KIND=
dp),
EXTERNAL :: dlange, pdlange, pdlatra
72 REAL(KIND=
sp),
EXTERNAL :: slange, pslange, pslatra
75 MODULE PROCEDURE cp_fm_trace_a0b0t0
76 MODULE PROCEDURE cp_fm_trace_a1b0t1_a
77 MODULE PROCEDURE cp_fm_trace_a1b0t1_p
78 MODULE PROCEDURE cp_fm_trace_a1b1t1_aa
79 MODULE PROCEDURE cp_fm_trace_a1b1t1_ap
80 MODULE PROCEDURE cp_fm_trace_a1b1t1_pa
81 MODULE PROCEDURE cp_fm_trace_a1b1t1_pp
85 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_aa
86 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_ap
87 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_pa
88 MODULE PROCEDURE cp_fm_contracted_trace_a2b2t2_pp
99 REAL(kind=
dp),
INTENT(OUT) :: det_a
100 REAL(kind=
dp) :: determinant
102 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
103 INTEGER :: n, i, info, p
104 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
105 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
diag
107#if defined(__parallel)
108 INTEGER :: myprow, nprow, npcol, nrow_local, nrow_block, irow_local
109 INTEGER,
DIMENSION(9) :: desca
113 matrix_struct=matrix_a%matrix_struct, &
117 a => matrix_lu%local_data
118 n = matrix_lu%matrix_struct%nrow_global
124#if defined(__parallel)
126 desca(:) = matrix_lu%matrix_struct%descriptor(:)
127 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
129 determinant = product(
diag)
130 myprow = matrix_lu%matrix_struct%context%mepos(1)
131 nprow = matrix_lu%matrix_struct%context%num_pe(1)
132 npcol = matrix_lu%matrix_struct%context%num_pe(2)
133 nrow_local = matrix_lu%matrix_struct%nrow_locals(myprow)
134 nrow_block = matrix_lu%matrix_struct%nrow_block
135 DO irow_local = 1, nrow_local
136 i = matrix_lu%matrix_struct%row_indices(irow_local)
137 IF (ipivot(irow_local) /= i) p = p + 1
139 CALL matrix_lu%matrix_struct%para_env%sum(p)
143 CALL dgetrf(n, n, a, n, ipivot, info)
145 determinant = product(
diag)
147 IF (ipivot(i) /= i) p = p + 1
153 det_a = determinant*(-2*mod(p, 2) + 1.0_dp)
167 REAL(kind=
dp),
INTENT(IN) :: alpha
169 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: beta
170 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_b
172 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_scale_and_add'
174 INTEGER :: handle, size_a, size_b
175 REAL(kind=
dp) :: my_beta
176 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
177 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp, b_sp
179 CALL timeset(routinen, handle)
182 IF (
PRESENT(matrix_b)) my_beta = 1.0_dp
183 IF (
PRESENT(beta)) my_beta = beta
186 IF (
PRESENT(beta))
THEN
187 cpassert(
PRESENT(matrix_b))
188 IF (
ASSOCIATED(matrix_a%local_data, matrix_b%local_data))
THEN
189 cpwarn(
"Bad use of routine. Call cp_fm_scale instead")
191 CALL timestop(handle)
196 a => matrix_a%local_data
197 a_sp => matrix_a%local_data_sp
199 IF (matrix_a%use_sp)
THEN
200 size_a =
SIZE(a_sp, 1)*
SIZE(a_sp, 2)
202 size_a =
SIZE(a, 1)*
SIZE(a, 2)
205 IF (alpha .NE. 1.0_dp)
THEN
206 IF (matrix_a%use_sp)
THEN
207 CALL sscal(size_a, real(alpha,
sp), a_sp, 1)
209 CALL dscal(size_a, alpha, a, 1)
212 IF (my_beta .NE. 0.0_dp)
THEN
213 IF (matrix_a%matrix_struct%context .NE. matrix_b%matrix_struct%context) &
214 cpabort(
"Matrices must be in the same blacs context")
217 matrix_b%matrix_struct))
THEN
219 b => matrix_b%local_data
220 b_sp => matrix_b%local_data_sp
221 IF (matrix_b%use_sp)
THEN
222 size_b =
SIZE(b_sp, 1)*
SIZE(b_sp, 2)
224 size_b =
SIZE(b, 1)*
SIZE(b, 2)
226 IF (size_a .NE. size_b) &
227 cpabort(
"Matrices must have same local sizes")
229 IF (matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
230 CALL saxpy(size_a, real(my_beta,
sp), b_sp, 1, a_sp, 1)
231 ELSEIF (matrix_a%use_sp .AND. .NOT. matrix_b%use_sp)
THEN
232 CALL saxpy(size_a, real(my_beta,
sp), real(b,
sp), 1, a_sp, 1)
233 ELSEIF (.NOT. matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
234 CALL daxpy(size_a, my_beta, real(b_sp,
dp), 1, a, 1)
236 CALL daxpy(size_a, my_beta, b, 1, a, 1)
241 cpabort(
"to do (pdscal,pdcopy,pdaxpy)")
249 CALL timestop(handle)
270 REAL(kind=
dp),
INTENT(IN) :: alpha, beta
271 CHARACTER,
INTENT(IN) :: trans
272 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
274 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_geadd'
276 INTEGER :: nrow_global, ncol_global, handle
277 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: aa, bb
278#if defined(__parallel)
279 INTEGER,
DIMENSION(9) :: desca, descb
284 CALL timeset(routinen, handle)
286 nrow_global = matrix_a%matrix_struct%nrow_global
287 ncol_global = matrix_a%matrix_struct%ncol_global
288 cpassert(nrow_global .EQ. matrix_b%matrix_struct%nrow_global)
289 cpassert(ncol_global .EQ. matrix_b%matrix_struct%ncol_global)
291 aa => matrix_a%local_data
292 bb => matrix_b%local_data
294#if defined(__parallel)
295 desca = matrix_a%matrix_struct%descriptor
296 descb = matrix_b%matrix_struct%descriptor
297 CALL pdgeadd(trans, &
309 CALL mkl_domatadd(
'C', trans,
'N', nrow_global, ncol_global, &
310 alpha, aa, nrow_global, beta, bb, nrow_global, bb, nrow_global)
316 DO jj = 1, ncol_global
317 DO ii = 1, nrow_global
318 bb(ii, jj) = beta*bb(ii, jj) + alpha*aa(jj, ii)
322 DO jj = 1, ncol_global
323 DO ii = 1, nrow_global
324 bb(ii, jj) = beta*bb(ii, jj) + alpha*aa(ii, jj)
330 CALL timestop(handle)
351 SUBROUTINE cp_fm_lu_decompose(matrix_a, almost_determinant, correct_sign)
353 REAL(kind=
dp),
INTENT(OUT) :: almost_determinant
354 LOGICAL,
INTENT(IN),
OPTIONAL :: correct_sign
356 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_lu_decompose'
358 INTEGER :: handle, i, info, n
359 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
360 REAL(kind=
dp) :: determinant
361 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
362#if defined(__parallel)
363 INTEGER,
DIMENSION(9) :: desca
364 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
diag
369 CALL timeset(routinen, handle)
371 a => matrix_a%local_data
372 n = matrix_a%matrix_struct%nrow_global
373 ALLOCATE (ipivot(n + matrix_a%matrix_struct%nrow_block))
375#if defined(__parallel)
376 mark_used(correct_sign)
377 desca(:) = matrix_a%matrix_struct%descriptor(:)
378 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
385 determinant = determinant*
diag(i)
390 CALL dgetrf(n, n, a, lda, ipivot, info)
392 IF (correct_sign)
THEN
394 IF (ipivot(i) .NE. i)
THEN
395 determinant = -determinant*a(i, i)
397 determinant = determinant*a(i, i)
402 determinant = determinant*a(i, i)
409 almost_determinant = determinant
410 CALL timestop(handle)
411 END SUBROUTINE cp_fm_lu_decompose
436 SUBROUTINE cp_fm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, &
437 matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, &
438 c_first_col, c_first_row)
440 CHARACTER(LEN=1),
INTENT(IN) :: transa, transb
441 INTEGER,
INTENT(IN) :: m, n, k
442 REAL(kind=
dp),
INTENT(IN) :: alpha
443 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
444 REAL(kind=
dp),
INTENT(IN) :: beta
446 INTEGER,
INTENT(IN),
OPTIONAL :: a_first_col, a_first_row, &
447 b_first_col, b_first_row, &
448 c_first_col, c_first_row
450 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_gemm'
452 INTEGER :: handle, i_a, i_b, i_c, j_a, &
454 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b, c
455 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp, b_sp, c_sp
456#if defined(__parallel)
457 INTEGER,
DIMENSION(9) :: desca, descb, descc
459 INTEGER :: lda, ldb, ldc
462 CALL timeset(routinen, handle)
467 a => matrix_a%local_data
468 b => matrix_b%local_data
469 c => matrix_c%local_data
471 a_sp => matrix_a%local_data_sp
472 b_sp => matrix_b%local_data_sp
473 c_sp => matrix_c%local_data_sp
476 IF (
PRESENT(a_first_row)) i_a = a_first_row
479 IF (
PRESENT(a_first_col)) j_a = a_first_col
482 IF (
PRESENT(b_first_row)) i_b = b_first_row
485 IF (
PRESENT(b_first_col)) j_b = b_first_col
488 IF (
PRESENT(c_first_row)) i_c = c_first_row
491 IF (
PRESENT(c_first_col)) j_c = c_first_col
493#if defined(__parallel)
495 desca(:) = matrix_a%matrix_struct%descriptor(:)
496 descb(:) = matrix_b%matrix_struct%descriptor(:)
497 descc(:) = matrix_c%matrix_struct%descriptor(:)
499 IF (matrix_a%use_sp .AND. matrix_b%use_sp .AND. matrix_c%use_sp)
THEN
501 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, &
502 descb, real(beta,
sp), c_sp(1, 1), i_c, j_c, descc)
504 ELSEIF ((.NOT. matrix_a%use_sp) .AND. (.NOT. matrix_b%use_sp) .AND. (.NOT. matrix_c%use_sp))
THEN
506 CALL pdgemm(transa, transb, m, n, k, alpha, a, i_a, j_a, desca, b, i_b, j_b, &
507 descb, beta, c, i_c, j_c, descc)
510 cpabort(
"Mixed precision gemm NYI")
514 IF (matrix_a%use_sp .AND. matrix_b%use_sp .AND. matrix_c%use_sp)
THEN
520 CALL sgemm(transa, transb, m, n, k, real(alpha,
sp), a_sp(i_a, j_a), lda, b_sp(i_b, j_b), ldb, &
521 REAL(beta,
sp), c_sp(i_c, j_c), ldc)
523 ELSEIF ((.NOT. matrix_a%use_sp) .AND. (.NOT. matrix_b%use_sp) .AND. (.NOT. matrix_c%use_sp))
THEN
529 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)
532 cpabort(
"Mixed precision gemm NYI")
536 CALL timestop(handle)
561 SUBROUTINE cp_fm_symm(side, uplo, m, n, alpha, matrix_a, matrix_b, beta, matrix_c)
563 CHARACTER(LEN=1),
INTENT(IN) :: side, uplo
564 INTEGER,
INTENT(IN) :: m, n
565 REAL(kind=
dp),
INTENT(IN) :: alpha
566 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
567 REAL(kind=
dp),
INTENT(IN) :: beta
570 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_symm'
573 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b, c
574#if defined(__parallel)
575 INTEGER,
DIMENSION(9) :: desca, descb, descc
577 INTEGER :: lda, ldb, ldc
580 CALL timeset(routinen, handle)
582 a => matrix_a%local_data
583 b => matrix_b%local_data
584 c => matrix_c%local_data
586#if defined(__parallel)
588 desca(:) = matrix_a%matrix_struct%descriptor(:)
589 descb(:) = matrix_b%matrix_struct%descriptor(:)
590 descc(:) = matrix_c%matrix_struct%descriptor(:)
592 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)
596 lda = matrix_a%matrix_struct%local_leading_dimension
597 ldb = matrix_b%matrix_struct%local_leading_dimension
598 ldc = matrix_c%matrix_struct%local_leading_dimension
600 CALL dsymm(side, uplo, m, n, alpha, a(1, 1), lda, b(1, 1), ldb, beta, c(1, 1), ldc)
603 CALL timestop(handle)
616 REAL(kind=
dp) :: norm
618 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_frobenius_norm'
620 INTEGER :: handle, size_a
621 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
622 REAL(kind=
dp),
EXTERNAL :: ddot
623#if defined(__parallel)
627 CALL timeset(routinen, handle)
630 a => matrix_a%local_data
631 size_a =
SIZE(a, 1)*
SIZE(a, 2)
632 norm = ddot(size_a, a(1, 1), 1, a(1, 1), 1)
633#if defined(__parallel)
634 group = matrix_a%matrix_struct%para_env
639 CALL timestop(handle)
658 SUBROUTINE cp_fm_syrk(uplo, trans, k, alpha, matrix_a, ia, ja, beta, matrix_c)
659 CHARACTER(LEN=1),
INTENT(IN) :: uplo, trans
660 INTEGER,
INTENT(IN) :: k
661 REAL(kind=
dp),
INTENT(IN) :: alpha
663 INTEGER,
INTENT(IN) :: ia, ja
664 REAL(kind=
dp),
INTENT(IN) :: beta
667 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_syrk'
670 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, c
671#if defined(__parallel)
672 INTEGER,
DIMENSION(9) :: desca, descc
677 CALL timeset(routinen, handle)
679 n = matrix_c%matrix_struct%nrow_global
681 a => matrix_a%local_data
682 c => matrix_c%local_data
684#if defined(__parallel)
686 desca(:) = matrix_a%matrix_struct%descriptor(:)
687 descc(:) = matrix_c%matrix_struct%descriptor(:)
689 CALL pdsyrk(uplo, trans, n, k, alpha, a(1, 1), ia, ja, desca, beta, c(1, 1), 1, 1, descc)
696 CALL dsyrk(uplo, trans, n, k, alpha, a(ia, ja), lda, beta, c(1, 1), ldc)
699 CALL timestop(handle)
713 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b, matrix_c
715 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_schur_product'
717 INTEGER :: handle, icol_local, irow_local, mypcol, &
718 myprow, ncol_local, &
720 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b, c
723 CALL timeset(routinen, handle)
725 context => matrix_a%matrix_struct%context
726 myprow = context%mepos(1)
727 mypcol = context%mepos(2)
729 a => matrix_a%local_data
730 b => matrix_b%local_data
731 c => matrix_c%local_data
733 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
734 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
736 DO icol_local = 1, ncol_local
737 DO irow_local = 1, nrow_local
738 c(irow_local, icol_local) = a(irow_local, icol_local)*b(irow_local, icol_local)
742 CALL timestop(handle)
759 SUBROUTINE cp_fm_trace_a0b0t0(matrix_a, matrix_b, trace)
761 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_b
762 REAL(KIND=
dp),
INTENT(OUT) :: trace
764 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a0b0t0'
766 INTEGER :: handle, mypcol, myprow, ncol_local, &
768 REAL(KIND=
dp),
DIMENSION(:, :),
POINTER :: a, b
769 REAL(KIND=
sp),
DIMENSION(:, :),
POINTER :: a_sp, b_sp
773 CALL timeset(routinen, handle)
775 context => matrix_a%matrix_struct%context
776 myprow = context%mepos(1)
777 mypcol = context%mepos(2)
779 group = matrix_a%matrix_struct%para_env
781 a => matrix_a%local_data
782 b => matrix_b%local_data
784 a_sp => matrix_a%local_data_sp
785 b_sp => matrix_b%local_data_sp
787 nrow_local = min(matrix_a%matrix_struct%nrow_locals(myprow), matrix_b%matrix_struct%nrow_locals(myprow))
788 ncol_local = min(matrix_a%matrix_struct%ncol_locals(mypcol), matrix_b%matrix_struct%ncol_locals(mypcol))
791 IF (matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
792 trace =
accurate_sum(real(a_sp(1:nrow_local, 1:ncol_local)* &
793 b_sp(1:nrow_local, 1:ncol_local),
dp))
794 ELSEIF (matrix_a%use_sp .AND. .NOT. matrix_b%use_sp)
THEN
795 trace =
accurate_sum(real(a_sp(1:nrow_local, 1:ncol_local),
dp)* &
796 b(1:nrow_local, 1:ncol_local))
797 ELSEIF (.NOT. matrix_a%use_sp .AND. matrix_b%use_sp)
THEN
799 REAL(b_sp(1:nrow_local, 1:ncol_local), dp))
802 b(1:nrow_local, 1:ncol_local))
805 CALL group%sum(trace)
807 CALL timestop(handle)
809 END SUBROUTINE cp_fm_trace_a0b0t0
830 SUBROUTINE cp_fm_trace_a1b0t1_a (matrix_a, matrix_b, trace)
831 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
833 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
835 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b0t1_a'
837 INTEGER :: handle, imatrix, n_matrices, &
838 ncols_local, nrows_local
839 LOGICAL :: use_sp_a, use_sp_b
840 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
841 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
844 CALL timeset(routinen, handle)
846 n_matrices =
SIZE(trace)
847 cpassert(
SIZE(matrix_a) == n_matrices)
849 CALL cp_fm_get_info(matrix_b, nrow_local=nrows_local, ncol_local=ncols_local)
850 use_sp_b = matrix_b%use_sp
853 ldata_b_sp => matrix_b%local_data_sp(1:nrows_local, 1:ncols_local)
855 ldata_b => matrix_b%local_data(1:nrows_local, 1:ncols_local)
863 DO imatrix = 1, n_matrices
865 use_sp_a = matrix_a(imatrix) %use_sp
868 IF (use_sp_a .AND. use_sp_b)
THEN
869 ldata_a_sp => matrix_a(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
871 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
872 ldata_a => matrix_a(imatrix) %local_data(1:nrows_local, 1:ncols_local)
875 cpabort(
"Matrices A and B are of different types")
880 group = matrix_b%matrix_struct%para_env
881 CALL group%sum(trace)
883 CALL timestop(handle)
884 END SUBROUTINE cp_fm_trace_a1b0t1_a
885 SUBROUTINE cp_fm_trace_a1b0t1_p (matrix_a, matrix_b, trace)
886 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
888 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
890 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b0t1_p'
892 INTEGER :: handle, imatrix, n_matrices, &
893 ncols_local, nrows_local
894 LOGICAL :: use_sp_a, use_sp_b
895 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
896 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
899 CALL timeset(routinen, handle)
901 n_matrices =
SIZE(trace)
902 cpassert(
SIZE(matrix_a) == n_matrices)
904 CALL cp_fm_get_info(matrix_b, nrow_local=nrows_local, ncol_local=ncols_local)
905 use_sp_b = matrix_b%use_sp
908 ldata_b_sp => matrix_b%local_data_sp(1:nrows_local, 1:ncols_local)
910 ldata_b => matrix_b%local_data(1:nrows_local, 1:ncols_local)
918 DO imatrix = 1, n_matrices
920 use_sp_a = matrix_a(imatrix) %matrix%use_sp
923 IF (use_sp_a .AND. use_sp_b)
THEN
924 ldata_a_sp => matrix_a(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
926 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
927 ldata_a => matrix_a(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
930 cpabort(
"Matrices A and B are of different types")
935 group = matrix_b%matrix_struct%para_env
936 CALL group%sum(trace)
938 CALL timestop(handle)
939 END SUBROUTINE cp_fm_trace_a1b0t1_p
959 SUBROUTINE cp_fm_trace_a1b1t1_aa (matrix_a, matrix_b, trace, accurate)
960 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
961 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
962 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
963 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
965 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_aa'
967 INTEGER :: handle, imatrix, n_matrices, &
968 ncols_local, nrows_local
969 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
970 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
971 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
974 CALL timeset(routinen, handle)
976 n_matrices =
SIZE(trace)
977 cpassert(
SIZE(matrix_a) == n_matrices)
978 cpassert(
SIZE(matrix_b) == n_matrices)
980 use_accurate_sum = .true.
981 IF (
PRESENT(accurate)) use_accurate_sum = accurate
987 DO imatrix = 1, n_matrices
988 CALL cp_fm_get_info(matrix_a(imatrix) , nrow_local=nrows_local, ncol_local=ncols_local)
990 use_sp_a = matrix_a(imatrix) %use_sp
991 use_sp_b = matrix_b(imatrix) %use_sp
994 IF (use_sp_a .AND. use_sp_b)
THEN
995 ldata_a_sp => matrix_a(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
996 ldata_b_sp => matrix_b(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
997 IF (use_accurate_sum)
THEN
1000 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1002 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1003 ldata_a => matrix_a(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1004 ldata_b => matrix_b(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1005 IF (use_accurate_sum)
THEN
1008 trace(imatrix) = sum(ldata_a*ldata_b)
1011 cpabort(
"Matrices A and B are of different types")
1016 group = matrix_a(1) %matrix_struct%para_env
1017 CALL group%sum(trace)
1019 CALL timestop(handle)
1020 END SUBROUTINE cp_fm_trace_a1b1t1_aa
1021 SUBROUTINE cp_fm_trace_a1b1t1_ap (matrix_a, matrix_b, trace, accurate)
1022 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1023 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1024 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1025 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1027 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_ap'
1029 INTEGER :: handle, imatrix, n_matrices, &
1030 ncols_local, nrows_local
1031 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1032 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1033 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1036 CALL timeset(routinen, handle)
1038 n_matrices =
SIZE(trace)
1039 cpassert(
SIZE(matrix_a) == n_matrices)
1040 cpassert(
SIZE(matrix_b) == n_matrices)
1042 use_accurate_sum = .true.
1043 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1049 DO imatrix = 1, n_matrices
1050 CALL cp_fm_get_info(matrix_a(imatrix) , nrow_local=nrows_local, ncol_local=ncols_local)
1052 use_sp_a = matrix_a(imatrix) %use_sp
1053 use_sp_b = matrix_b(imatrix) %matrix%use_sp
1056 IF (use_sp_a .AND. use_sp_b)
THEN
1057 ldata_a_sp => matrix_a(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1058 ldata_b_sp => matrix_b(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1059 IF (use_accurate_sum)
THEN
1062 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1064 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1065 ldata_a => matrix_a(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1066 ldata_b => matrix_b(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1067 IF (use_accurate_sum)
THEN
1070 trace(imatrix) = sum(ldata_a*ldata_b)
1073 cpabort(
"Matrices A and B are of different types")
1078 group = matrix_a(1) %matrix_struct%para_env
1079 CALL group%sum(trace)
1081 CALL timestop(handle)
1082 END SUBROUTINE cp_fm_trace_a1b1t1_ap
1083 SUBROUTINE cp_fm_trace_a1b1t1_pa (matrix_a, matrix_b, trace, accurate)
1084 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1085 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1086 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1087 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1089 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_pa'
1091 INTEGER :: handle, imatrix, n_matrices, &
1092 ncols_local, nrows_local
1093 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1094 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1095 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1098 CALL timeset(routinen, handle)
1100 n_matrices =
SIZE(trace)
1101 cpassert(
SIZE(matrix_a) == n_matrices)
1102 cpassert(
SIZE(matrix_b) == n_matrices)
1104 use_accurate_sum = .true.
1105 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1111 DO imatrix = 1, n_matrices
1112 CALL cp_fm_get_info(matrix_a(imatrix) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1114 use_sp_a = matrix_a(imatrix) %matrix%use_sp
1115 use_sp_b = matrix_b(imatrix) %use_sp
1118 IF (use_sp_a .AND. use_sp_b)
THEN
1119 ldata_a_sp => matrix_a(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1120 ldata_b_sp => matrix_b(imatrix) %local_data_sp(1:nrows_local, 1:ncols_local)
1121 IF (use_accurate_sum)
THEN
1124 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1126 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1127 ldata_a => matrix_a(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1128 ldata_b => matrix_b(imatrix) %local_data(1:nrows_local, 1:ncols_local)
1129 IF (use_accurate_sum)
THEN
1132 trace(imatrix) = sum(ldata_a*ldata_b)
1135 cpabort(
"Matrices A and B are of different types")
1140 group = matrix_a(1) %matrix%matrix_struct%para_env
1141 CALL group%sum(trace)
1143 CALL timestop(handle)
1144 END SUBROUTINE cp_fm_trace_a1b1t1_pa
1145 SUBROUTINE cp_fm_trace_a1b1t1_pp (matrix_a, matrix_b, trace, accurate)
1146 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_a
1147 TYPE(
cp_fm_p_type),
DIMENSION(:),
INTENT(IN) :: matrix_b
1148 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: trace
1149 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1151 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_trace_a1b1t1_pp'
1153 INTEGER :: handle, imatrix, n_matrices, &
1154 ncols_local, nrows_local
1155 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1156 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1157 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1160 CALL timeset(routinen, handle)
1162 n_matrices =
SIZE(trace)
1163 cpassert(
SIZE(matrix_a) == n_matrices)
1164 cpassert(
SIZE(matrix_b) == n_matrices)
1166 use_accurate_sum = .true.
1167 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1173 DO imatrix = 1, n_matrices
1174 CALL cp_fm_get_info(matrix_a(imatrix) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1176 use_sp_a = matrix_a(imatrix) %matrix%use_sp
1177 use_sp_b = matrix_b(imatrix) %matrix%use_sp
1180 IF (use_sp_a .AND. use_sp_b)
THEN
1181 ldata_a_sp => matrix_a(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1182 ldata_b_sp => matrix_b(imatrix) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1183 IF (use_accurate_sum)
THEN
1186 trace(imatrix) = sum(ldata_a_sp*ldata_b_sp)
1188 ELSE IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1189 ldata_a => matrix_a(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1190 ldata_b => matrix_b(imatrix) %matrix%local_data(1:nrows_local, 1:ncols_local)
1191 IF (use_accurate_sum)
THEN
1194 trace(imatrix) = sum(ldata_a*ldata_b)
1197 cpabort(
"Matrices A and B are of different types")
1202 group = matrix_a(1) %matrix%matrix_struct%para_env
1203 CALL group%sum(trace)
1205 CALL timestop(handle)
1206 END SUBROUTINE cp_fm_trace_a1b1t1_pp
1215 SUBROUTINE cp_fm_contracted_trace_a2b2t2_aa (matrix_a, matrix_b, trace, accurate)
1216 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1217 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1218 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1219 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1221 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_aa'
1223 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1225 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1226 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1228 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1229 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1232 CALL timeset(routinen, handle)
1234 nz =
SIZE(matrix_a, 1)
1235 cpassert(
SIZE(matrix_b, 1) == nz)
1237 na =
SIZE(matrix_a, 2)
1238 nb =
SIZE(matrix_b, 2)
1239 cpassert(
SIZE(trace, 1) == na)
1240 cpassert(
SIZE(trace, 2) == nb)
1242 use_accurate_sum = .true.
1243 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1248 na8 = int(na, kind=
int_8)
1254 DO itrace = 1, ntraces
1255 ib8 = (itrace - 1)/na8
1256 ia = int(itrace - ib8*na8)
1261 CALL cp_fm_get_info(matrix_a(iz, ia) , nrow_local=nrows_local, ncol_local=ncols_local)
1262 use_sp_a = matrix_a(iz, ia) %use_sp
1263 use_sp_b = matrix_b(iz, ib) %use_sp
1266 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1267 ldata_a => matrix_a(iz, ia) %local_data(1:nrows_local, 1:ncols_local)
1268 ldata_b => matrix_b(iz, ib) %local_data(1:nrows_local, 1:ncols_local)
1269 IF (use_accurate_sum)
THEN
1272 t = t + sum(ldata_a*ldata_b)
1274 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1275 ldata_a_sp => matrix_a(iz, ia) %local_data_sp(1:nrows_local, 1:ncols_local)
1276 ldata_b_sp => matrix_b(iz, ib) %local_data_sp(1:nrows_local, 1:ncols_local)
1277 IF (use_accurate_sum)
THEN
1280 t = t + sum(ldata_a_sp*ldata_b_sp)
1283 cpabort(
"Matrices A and B are of different types")
1290 group = matrix_a(1, 1) %matrix_struct%para_env
1291 CALL group%sum(trace)
1293 CALL timestop(handle)
1294 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_aa
1295 SUBROUTINE cp_fm_contracted_trace_a2b2t2_ap (matrix_a, matrix_b, trace, accurate)
1296 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1297 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1298 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1299 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1301 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_ap'
1303 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1305 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1306 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1308 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1309 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1312 CALL timeset(routinen, handle)
1314 nz =
SIZE(matrix_a, 1)
1315 cpassert(
SIZE(matrix_b, 1) == nz)
1317 na =
SIZE(matrix_a, 2)
1318 nb =
SIZE(matrix_b, 2)
1319 cpassert(
SIZE(trace, 1) == na)
1320 cpassert(
SIZE(trace, 2) == nb)
1322 use_accurate_sum = .true.
1323 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1328 na8 = int(na, kind=
int_8)
1334 DO itrace = 1, ntraces
1335 ib8 = (itrace - 1)/na8
1336 ia = int(itrace - ib8*na8)
1341 CALL cp_fm_get_info(matrix_a(iz, ia) , nrow_local=nrows_local, ncol_local=ncols_local)
1342 use_sp_a = matrix_a(iz, ia) %use_sp
1343 use_sp_b = matrix_b(iz, ib) %matrix%use_sp
1346 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1347 ldata_a => matrix_a(iz, ia) %local_data(1:nrows_local, 1:ncols_local)
1348 ldata_b => matrix_b(iz, ib) %matrix%local_data(1:nrows_local, 1:ncols_local)
1349 IF (use_accurate_sum)
THEN
1352 t = t + sum(ldata_a*ldata_b)
1354 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1355 ldata_a_sp => matrix_a(iz, ia) %local_data_sp(1:nrows_local, 1:ncols_local)
1356 ldata_b_sp => matrix_b(iz, ib) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1357 IF (use_accurate_sum)
THEN
1360 t = t + sum(ldata_a_sp*ldata_b_sp)
1363 cpabort(
"Matrices A and B are of different types")
1370 group = matrix_a(1, 1) %matrix_struct%para_env
1371 CALL group%sum(trace)
1373 CALL timestop(handle)
1374 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_ap
1375 SUBROUTINE cp_fm_contracted_trace_a2b2t2_pa (matrix_a, matrix_b, trace, accurate)
1376 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1377 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1378 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1379 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1381 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_pa'
1383 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1385 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1386 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1388 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1389 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1392 CALL timeset(routinen, handle)
1394 nz =
SIZE(matrix_a, 1)
1395 cpassert(
SIZE(matrix_b, 1) == nz)
1397 na =
SIZE(matrix_a, 2)
1398 nb =
SIZE(matrix_b, 2)
1399 cpassert(
SIZE(trace, 1) == na)
1400 cpassert(
SIZE(trace, 2) == nb)
1402 use_accurate_sum = .true.
1403 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1408 na8 = int(na, kind=
int_8)
1414 DO itrace = 1, ntraces
1415 ib8 = (itrace - 1)/na8
1416 ia = int(itrace - ib8*na8)
1421 CALL cp_fm_get_info(matrix_a(iz, ia) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1422 use_sp_a = matrix_a(iz, ia) %matrix%use_sp
1423 use_sp_b = matrix_b(iz, ib) %use_sp
1426 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1427 ldata_a => matrix_a(iz, ia) %matrix%local_data(1:nrows_local, 1:ncols_local)
1428 ldata_b => matrix_b(iz, ib) %local_data(1:nrows_local, 1:ncols_local)
1429 IF (use_accurate_sum)
THEN
1432 t = t + sum(ldata_a*ldata_b)
1434 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1435 ldata_a_sp => matrix_a(iz, ia) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1436 ldata_b_sp => matrix_b(iz, ib) %local_data_sp(1:nrows_local, 1:ncols_local)
1437 IF (use_accurate_sum)
THEN
1440 t = t + sum(ldata_a_sp*ldata_b_sp)
1443 cpabort(
"Matrices A and B are of different types")
1450 group = matrix_a(1, 1) %matrix%matrix_struct%para_env
1451 CALL group%sum(trace)
1453 CALL timestop(handle)
1454 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_pa
1455 SUBROUTINE cp_fm_contracted_trace_a2b2t2_pp (matrix_a, matrix_b, trace, accurate)
1456 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_a
1457 TYPE(
cp_fm_p_type),
DIMENSION(:, :),
INTENT(IN) :: matrix_b
1458 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: trace
1459 LOGICAL,
INTENT(IN),
OPTIONAL :: accurate
1461 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_fm_contracted_trace_a2b2t2_pp'
1463 INTEGER :: handle, ia, ib, iz, na, nb, ncols_local, &
1465 INTEGER(kind=int_8) :: ib8, itrace, na8, ntraces
1466 LOGICAL :: use_accurate_sum, use_sp_a, use_sp_b
1468 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ldata_a, ldata_b
1469 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: ldata_a_sp, ldata_b_sp
1472 CALL timeset(routinen, handle)
1474 nz =
SIZE(matrix_a, 1)
1475 cpassert(
SIZE(matrix_b, 1) == nz)
1477 na =
SIZE(matrix_a, 2)
1478 nb =
SIZE(matrix_b, 2)
1479 cpassert(
SIZE(trace, 1) == na)
1480 cpassert(
SIZE(trace, 2) == nb)
1482 use_accurate_sum = .true.
1483 IF (
PRESENT(accurate)) use_accurate_sum = accurate
1488 na8 = int(na, kind=
int_8)
1494 DO itrace = 1, ntraces
1495 ib8 = (itrace - 1)/na8
1496 ia = int(itrace - ib8*na8)
1501 CALL cp_fm_get_info(matrix_a(iz, ia) %matrix, nrow_local=nrows_local, ncol_local=ncols_local)
1502 use_sp_a = matrix_a(iz, ia) %matrix%use_sp
1503 use_sp_b = matrix_b(iz, ib) %matrix%use_sp
1506 IF (.NOT. use_sp_a .AND. .NOT. use_sp_b)
THEN
1507 ldata_a => matrix_a(iz, ia) %matrix%local_data(1:nrows_local, 1:ncols_local)
1508 ldata_b => matrix_b(iz, ib) %matrix%local_data(1:nrows_local, 1:ncols_local)
1509 IF (use_accurate_sum)
THEN
1512 t = t + sum(ldata_a*ldata_b)
1514 ELSE IF (use_sp_a .AND. use_sp_b)
THEN
1515 ldata_a_sp => matrix_a(iz, ia) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1516 ldata_b_sp => matrix_b(iz, ib) %matrix%local_data_sp(1:nrows_local, 1:ncols_local)
1517 IF (use_accurate_sum)
THEN
1520 t = t + sum(ldata_a_sp*ldata_b_sp)
1523 cpabort(
"Matrices A and B are of different types")
1530 group = matrix_a(1, 1) %matrix%matrix_struct%para_env
1531 CALL group%sum(trace)
1533 CALL timestop(handle)
1534 END SUBROUTINE cp_fm_contracted_trace_a2b2t2_pp
1570 transpose_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, &
1572 TYPE(
cp_fm_type),
INTENT(IN) :: triangular_matrix, matrix_b
1573 CHARACTER,
INTENT(IN),
OPTIONAL :: side
1574 LOGICAL,
INTENT(IN),
OPTIONAL :: transpose_tr, invert_tr
1575 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo_tr
1576 LOGICAL,
INTENT(IN),
OPTIONAL :: unit_diag_tr
1577 INTEGER,
INTENT(IN),
OPTIONAL :: n_rows, n_cols
1578 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: alpha
1580 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_triangular_multiply'
1582 CHARACTER :: side_char, transa, unit_diag, uplo
1583 INTEGER :: handle, mdim, m, n
1587 CALL timeset(routinen, handle)
1595 IF (
PRESENT(side)) side_char = side
1596 mdim = merge(1, 2,
'L' .EQ. side_char)
1597 IF (
PRESENT(invert_tr)) invert = invert_tr
1598 IF (
PRESENT(uplo_tr)) uplo = uplo_tr
1599 IF (
PRESENT(unit_diag_tr))
THEN
1600 IF (unit_diag_tr)
THEN
1606 IF (
PRESENT(transpose_tr))
THEN
1607 IF (transpose_tr)
THEN
1613 IF (
PRESENT(alpha)) al = alpha
1614 IF (
PRESENT(n_rows)) m = n_rows
1615 IF (
PRESENT(n_cols)) n = n_cols
1619#if defined(__parallel)
1620 CALL pdtrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1621 triangular_matrix%local_data(1, 1), 1, 1, &
1622 triangular_matrix%matrix_struct%descriptor, &
1623 matrix_b%local_data(1, 1), 1, 1, &
1624 matrix_b%matrix_struct%descriptor(1))
1626 CALL dtrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1627 triangular_matrix%local_data(1, 1), &
1628 SIZE(triangular_matrix%local_data, mdim), &
1629 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1634#if defined(__parallel)
1635 CALL pdtrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1636 triangular_matrix%local_data(1, 1), 1, 1, &
1637 triangular_matrix%matrix_struct%descriptor, &
1638 matrix_b%local_data(1, 1), 1, 1, &
1639 matrix_b%matrix_struct%descriptor(1))
1641 CALL dtrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1642 triangular_matrix%local_data(1, 1), &
1643 SIZE(triangular_matrix%local_data, mdim), &
1644 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1649 CALL timestop(handle)
1661 REAL(kind=
dp),
INTENT(IN) :: alpha
1664 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_scale'
1666 INTEGER :: handle, size_a
1667 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1669 CALL timeset(routinen, handle)
1673 a => matrix_a%local_data
1674 size_a =
SIZE(a, 1)*
SIZE(a, 2)
1676 CALL dscal(size_a, alpha, a, 1)
1678 CALL timestop(handle)
1691 TYPE(
cp_fm_type),
INTENT(IN) :: matrix, matrixt
1693 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_transpose'
1695 INTEGER :: handle, ncol_global, &
1696 nrow_global, ncol_globalt, nrow_globalt
1697 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, c
1698#if defined(__parallel)
1699 INTEGER,
DIMENSION(9) :: desca, descc
1700#elif !defined(__MKL)
1704 nrow_global = matrix%matrix_struct%nrow_global
1705 ncol_global = matrix%matrix_struct%ncol_global
1706 nrow_globalt = matrixt%matrix_struct%nrow_global
1707 ncol_globalt = matrixt%matrix_struct%ncol_global
1708 cpassert(nrow_global == ncol_globalt)
1709 cpassert(nrow_globalt == ncol_global)
1711 CALL timeset(routinen, handle)
1713 a => matrix%local_data
1714 c => matrixt%local_data
1716#if defined(__parallel)
1717 desca(:) = matrix%matrix_struct%descriptor(:)
1718 descc(:) = matrixt%matrix_struct%descriptor(:)
1719 CALL pdtran(ncol_global, nrow_global, 1.0_dp, a(1, 1), 1, 1, desca, 0.0_dp, c(1, 1), 1, 1, descc)
1721 CALL mkl_domatcopy(
'C',
'T', nrow_global, ncol_global, 1.0_dp, a(1, 1), nrow_global, c(1, 1), ncol_global)
1723 DO j = 1, ncol_global
1724 DO i = 1, nrow_global
1729 CALL timestop(handle)
1745 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
1747 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_uplo_to_full'
1750 INTEGER :: handle, icol_global, irow_global, &
1751 mypcol, myprow, ncol_global, &
1753 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1754 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
1757#if defined(__parallel)
1758 INTEGER :: icol_local, irow_local, &
1759 ncol_block, ncol_local, &
1760 nrow_block, nrow_local
1761 INTEGER,
DIMENSION(9) :: desca, descc
1762 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: c
1763 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: c_sp
1767 IF (
PRESENT(uplo)) myuplo = uplo
1769 nrow_global = matrix%matrix_struct%nrow_global
1770 ncol_global = matrix%matrix_struct%ncol_global
1771 cpassert(nrow_global == ncol_global)
1772 nrow_global = work%matrix_struct%nrow_global
1773 ncol_global = work%matrix_struct%ncol_global
1774 cpassert(nrow_global == ncol_global)
1775 cpassert(matrix%use_sp .EQV. work%use_sp)
1777 CALL timeset(routinen, handle)
1779 context => matrix%matrix_struct%context
1780 myprow = context%mepos(1)
1781 mypcol = context%mepos(2)
1783#if defined(__parallel)
1785 nrow_block = matrix%matrix_struct%nrow_block
1786 ncol_block = matrix%matrix_struct%ncol_block
1788 nrow_local = matrix%matrix_struct%nrow_locals(myprow)
1789 ncol_local = matrix%matrix_struct%ncol_locals(mypcol)
1791 a => work%local_data
1792 a_sp => work%local_data_sp
1793 desca(:) = work%matrix_struct%descriptor(:)
1794 c => matrix%local_data
1795 c_sp => matrix%local_data_sp
1796 descc(:) = matrix%matrix_struct%descriptor(:)
1798 DO icol_local = 1, ncol_local
1799 icol_global = matrix%matrix_struct%col_indices(icol_local)
1800 DO irow_local = 1, nrow_local
1801 irow_global = matrix%matrix_struct%row_indices(irow_local)
1802 IF (merge(irow_global > icol_global, irow_global < icol_global, (myuplo ==
"U") .OR. (myuplo ==
"u")))
THEN
1803 IF (matrix%use_sp)
THEN
1804 c_sp(irow_local, icol_local) = 0.0_sp
1806 c(irow_local, icol_local) = 0.0_dp
1808 ELSE IF (irow_global == icol_global)
THEN
1809 IF (matrix%use_sp)
THEN
1810 c_sp(irow_local, icol_local) = 0.5_sp*c_sp(irow_local, icol_local)
1812 c(irow_local, icol_local) = 0.5_dp*c(irow_local, icol_local)
1818 DO icol_local = 1, ncol_local
1819 DO irow_local = 1, nrow_local
1820 IF (matrix%use_sp)
THEN
1821 a_sp(irow_local, icol_local) = c_sp(irow_local, icol_local)
1823 a(irow_local, icol_local) = c(irow_local, icol_local)
1828 IF (matrix%use_sp)
THEN
1829 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)
1831 CALL pdtran(nrow_global, ncol_global, 1.0_dp, a(1, 1), 1, 1, desca, 1.0_dp, c(1, 1), 1, 1, descc)
1836 a => matrix%local_data
1837 a_sp => matrix%local_data_sp
1839 IF ((myuplo ==
"U") .OR. (myuplo ==
"u"))
THEN
1840 DO irow_global = 1, nrow_global
1841 DO icol_global = irow_global + 1, ncol_global
1842 IF (matrix%use_sp)
THEN
1843 a_sp(icol_global, irow_global) = a_sp(irow_global, icol_global)
1845 a(icol_global, irow_global) = a(irow_global, icol_global)
1850 DO icol_global = 1, ncol_global
1851 DO irow_global = icol_global + 1, nrow_global
1852 IF (matrix%use_sp)
THEN
1853 a_sp(irow_global, icol_global) = a_sp(icol_global, irow_global)
1855 a(irow_global, icol_global) = a(icol_global, irow_global)
1862 CALL timestop(handle)
1880 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: scaling
1882 INTEGER :: k, mypcol, myprow, n, ncol_global, &
1884 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1885 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
1886#if defined(__parallel)
1887 INTEGER :: icol_global, icol_local, &
1888 ipcol, iprow, irow_local
1893 myprow = matrixa%matrix_struct%context%mepos(1)
1894 mypcol = matrixa%matrix_struct%context%mepos(2)
1895 nprow = matrixa%matrix_struct%context%num_pe(1)
1896 npcol = matrixa%matrix_struct%context%num_pe(2)
1898 ncol_global = matrixa%matrix_struct%ncol_global
1900 a => matrixa%local_data
1901 a_sp => matrixa%local_data_sp
1902 IF (matrixa%use_sp)
THEN
1907 k = min(
SIZE(scaling), ncol_global)
1909#if defined(__parallel)
1911 DO icol_global = 1, k
1912 CALL infog2l(1, icol_global, matrixa%matrix_struct%descriptor, &
1913 nprow, npcol, myprow, mypcol, &
1914 irow_local, icol_local, iprow, ipcol)
1915 IF ((ipcol == mypcol))
THEN
1916 IF (matrixa%use_sp)
THEN
1917 CALL sscal(n, real(scaling(icol_global),
sp), a_sp(:, icol_local), 1)
1919 CALL dscal(n, scaling(icol_global), a(:, icol_local), 1)
1925 IF (matrixa%use_sp)
THEN
1926 CALL sscal(n, real(scaling(i),
sp), a_sp(:, i), 1)
1928 CALL dscal(n, scaling(i), a(:, i), 1)
1943 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: scaling
1945 INTEGER :: n, m, nrow_global, nrow_local, ncol_local
1946 INTEGER,
DIMENSION(:),
POINTER :: row_indices
1947 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
1948 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
1949#if defined(__parallel)
1950 INTEGER :: irow_global, icol, irow
1955 CALL cp_fm_get_info(matrixa, row_indices=row_indices, nrow_global=nrow_global, &
1956 nrow_local=nrow_local, ncol_local=ncol_local)
1957 cpassert(
SIZE(scaling) == nrow_global)
1959 a => matrixa%local_data
1960 a_sp => matrixa%local_data_sp
1961 IF (matrixa%use_sp)
THEN
1969#if defined(__parallel)
1970 DO icol = 1, ncol_local
1971 IF (matrixa%use_sp)
THEN
1972 DO irow = 1, nrow_local
1973 irow_global = row_indices(irow)
1974 a(irow, icol) = real(scaling(irow_global),
dp)*a(irow, icol)
1977 DO irow = 1, nrow_local
1978 irow_global = row_indices(irow)
1979 a(irow, icol) = scaling(irow_global)*a(irow, icol)
1984 IF (matrixa%use_sp)
THEN
1986 a_sp(1:n, j) = real(scaling(1:n),
sp)*a_sp(1:n, j)
1990 a(1:n, j) = scaling(1:n)*a(1:n, j)
2014 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_inverse
2015 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: det_a
2016 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_svd
2017 REAL(kind=
dp),
DIMENSION(:),
POINTER, &
2018 INTENT(INOUT),
OPTIONAL :: eigval
2021 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
2022 REAL(kind=
dp) :: determinant, my_eps_svd
2023 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2026#if defined(__parallel)
2027 TYPE(
cp_fm_type) :: u, vt, sigma, inv_sigma_ut
2029 INTEGER :: i, info, liwork, lwork, exponent_of_minus_one
2030 INTEGER,
DIMENSION(9) :: desca
2032 REAL(kind=
dp) :: alpha, beta
2033 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
diag
2034 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
2037 REAL(kind=
dp) :: eps1
2041 IF (
PRESENT(eps_svd)) my_eps_svd = eps_svd
2044 matrix_struct=matrix_a%matrix_struct, &
2048 a => matrix_lu%local_data
2049 n = matrix_lu%matrix_struct%nrow_global
2050 ALLOCATE (ipivot(n + matrix_a%matrix_struct%nrow_block))
2052#if defined(__parallel)
2053 IF (my_eps_svd .EQ. 0.0_dp)
THEN
2057 desca(:) = matrix_lu%matrix_struct%descriptor(:)
2058 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
2060 IF (
PRESENT(det_a) .OR.
PRESENT(eigval))
THEN
2066 exponent_of_minus_one = 0
2067 determinant = 1.0_dp
2069 determinant = determinant*
diag(i)
2070 IF (ipivot(i) .NE. i)
THEN
2071 exponent_of_minus_one = exponent_of_minus_one + 1
2074 IF (
PRESENT(eigval))
THEN
2075 cpassert(.NOT.
ASSOCIATED(eigval))
2076 ALLOCATE (eigval(n))
2081 group = matrix_lu%matrix_struct%para_env
2082 CALL group%sum(exponent_of_minus_one)
2084 determinant = determinant*(-1.0_dp)**exponent_of_minus_one
2091 CALL pdgetrs(
'N', n, n, matrix_lu%local_data, 1, 1, desca, ipivot, matrix_inverse%local_data, 1, 1, desca, info)
2095 matrix_struct=matrix_a%matrix_struct, &
2096 name=
"LEFT_SINGULAR_MATRIX")
2099 matrix_struct=matrix_a%matrix_struct, &
2100 name=
"RIGHT_SINGULAR_MATRIX")
2104 desca(:) = matrix_lu%matrix_struct%descriptor(:)
2108 CALL pdgesvd(
'V',
'V', n, n, matrix_lu%local_data, 1, 1, desca,
diag, u%local_data, &
2109 1, 1, desca, vt%local_data, 1, 1, desca, work, lwork, info)
2110 lwork = int(work(1))
2112 ALLOCATE (work(lwork))
2114 CALL pdgesvd(
'V',
'V', n, n, matrix_lu%local_data, 1, 1, desca,
diag, u%local_data, &
2115 1, 1, desca, vt%local_data, 1, 1, desca, work, lwork, info)
2118 IF (info /= 0 .AND. info /= n + 1) &
2119 cpabort(
"Singular value decomposition of matrix failed.")
2122 matrix_struct=matrix_a%matrix_struct, &
2123 name=
"SINGULAR_VALUE_MATRIX")
2125 determinant = 1.0_dp
2127 IF (
PRESENT(eigval))
THEN
2128 cpassert(.NOT.
ASSOCIATED(eigval))
2129 ALLOCATE (eigval(n))
2133 IF (
diag(i) < my_eps_svd)
THEN
2137 determinant = determinant*
diag(i)
2144 CALL cp_warn(__location__, &
2145 "Linear dependencies were detected in the SVD inversion of matrix "//trim(adjustl(matrix_a%name))// &
2146 ". At least one singular value has been quenched.")
2149 matrix_struct=matrix_a%matrix_struct, &
2150 name=
"SINGULAR_VALUE_MATRIX")
2152 CALL pdgemm(
'N',
'T', n, n, n, 1.0_dp, sigma%local_data, 1, 1, desca, &
2153 u%local_data, 1, 1, desca, 0.0_dp, inv_sigma_ut%local_data, 1, 1, desca)
2156 CALL pdgemm(
'T',
'N', n, n, n, 1.0_dp, vt%local_data, 1, 1, desca, &
2157 inv_sigma_ut%local_data, 1, 1, desca, 0.0_dp, matrix_inverse%local_data, 1, 1, desca)
2166 IF (my_eps_svd .EQ. 0.0_dp)
THEN
2168 CALL invert_matrix(matrix_a%local_data, matrix_inverse%local_data, &
2170 CALL cp_fm_lu_decompose(matrix_lu, determinant, correct_sign=sign)
2171 IF (
PRESENT(eigval)) &
2172 CALL cp_abort(__location__, &
2173 "NYI. Eigenvalues not available for return without SCALAPACK.")
2176 determinant, eigval)
2181 IF (
PRESENT(det_a)) det_a = determinant
2193 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo_tr
2195 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_triangular_invert'
2197 CHARACTER :: unit_diag, uplo
2198 INTEGER :: handle, info, ncol_global
2199 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2200#if defined(__parallel)
2201 INTEGER,
DIMENSION(9) :: desca
2204 CALL timeset(routinen, handle)
2208 IF (
PRESENT(uplo_tr)) uplo = uplo_tr
2210 ncol_global = matrix_a%matrix_struct%ncol_global
2212 a => matrix_a%local_data
2214#if defined(__parallel)
2215 desca(:) = matrix_a%matrix_struct%descriptor(:)
2217 CALL pdtrtri(uplo, unit_diag, ncol_global, a(1, 1), 1, 1, desca, info)
2220 CALL dtrtri(uplo, unit_diag, ncol_global, a(1, 1), ncol_global, info)
2223 CALL timestop(handle)
2239 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, matrix_r
2240 INTEGER,
INTENT(IN),
OPTIONAL :: nrow_fact, ncol_fact, &
2241 first_row, first_col
2242 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
2244 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_qr_factorization'
2247 INTEGER :: handle, i, icol, info, irow, &
2248 j, lda, lwork, ncol, &
2250 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tau, work
2251 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: r_mat
2252 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2253#if defined(__parallel)
2254 INTEGER,
DIMENSION(9) :: desca
2257 CALL timeset(routinen, handle)
2260 IF (
PRESENT(uplo)) myuplo = uplo
2262 ncol = matrix_a%matrix_struct%ncol_global
2263 nrow = matrix_a%matrix_struct%nrow_global
2266 a => matrix_a%local_data
2268 IF (
PRESENT(nrow_fact)) nrow = nrow_fact
2269 IF (
PRESENT(ncol_fact)) ncol = ncol_fact
2271 IF (
PRESENT(first_row)) irow = first_row
2273 IF (
PRESENT(first_col)) icol = first_col
2275 cpassert(nrow >= ncol)
2277 ALLOCATE (tau(ndim))
2279#if defined(__parallel)
2281 desca(:) = matrix_a%matrix_struct%descriptor(:)
2284 ALLOCATE (work(2*ndim))
2285 CALL pdgeqrf(nrow, ncol, a, irow, icol, desca, tau, work, lwork, info)
2286 lwork = int(work(1))
2288 ALLOCATE (work(lwork))
2289 CALL pdgeqrf(nrow, ncol, a, irow, icol, desca, tau, work, lwork, info)
2293 ALLOCATE (work(2*ndim))
2294 CALL dgeqrf(nrow, ncol, a, lda, tau, work, lwork, info)
2295 lwork = int(work(1))
2297 ALLOCATE (work(lwork))
2298 CALL dgeqrf(nrow, ncol, a, lda, tau, work, lwork, info)
2302 ALLOCATE (r_mat(ncol, ncol))
2304 IF ((myuplo ==
"U") .OR. (myuplo ==
"u"))
THEN
2307 r_mat(j, i) = 0.0_dp
2313 r_mat(i, j) = 0.0_dp
2319 DEALLOCATE (tau, work, r_mat)
2321 CALL timestop(handle)
2332 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_a, general_a
2334 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_solve'
2336 INTEGER :: handle, info, n, nrhs
2337 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
2338 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, a_general
2339#if defined(__parallel)
2340 INTEGER,
DIMENSION(9) :: desca, descb
2345 CALL timeset(routinen, handle)
2347 a => matrix_a%local_data
2348 a_general => general_a%local_data
2349 n = matrix_a%matrix_struct%nrow_global
2350 nrhs = general_a%matrix_struct%ncol_global
2351 ALLOCATE (ipivot(n + matrix_a%matrix_struct%nrow_block))
2353#if defined(__parallel)
2354 desca(:) = matrix_a%matrix_struct%descriptor(:)
2355 descb(:) = general_a%matrix_struct%descriptor(:)
2356 CALL pdgetrf(n, n, a, 1, 1, desca, ipivot, info)
2357 CALL pdgetrs(
"N", n, nrhs, a, 1, 1, desca, ipivot, a_general, &
2362 ldb =
SIZE(a_general, 1)
2363 CALL dgetrf(n, n, a, lda, ipivot, info)
2364 CALL dgetrs(
"N", n, nrhs, a, lda, ipivot, a_general, ldb, info)
2370 CALL timestop(handle)
2401 SUBROUTINE cp_complex_fm_gemm(transa, transb, m, n, k, alpha, A_re, A_im, B_re, B_im, beta, &
2402 C_re, C_im, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, &
2404 CHARACTER(LEN=1),
INTENT(IN) :: transa, transb
2405 INTEGER,
INTENT(IN) :: m, n, k
2406 REAL(kind=
dp),
INTENT(IN) :: alpha
2407 TYPE(
cp_fm_type),
INTENT(IN) :: a_re, a_im, b_re, b_im
2408 REAL(kind=
dp),
INTENT(IN) :: beta
2410 INTEGER,
INTENT(IN),
OPTIONAL :: a_first_col, a_first_row, b_first_col, &
2411 b_first_row, c_first_col, c_first_row
2413 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_complex_fm_gemm'
2417 CALL timeset(routinen, handle)
2419 CALL cp_fm_gemm(transa, transb, m, n, k, alpha, a_re, b_re, beta, c_re, &
2420 a_first_col=a_first_col, &
2421 a_first_row=a_first_row, &
2422 b_first_col=b_first_col, &
2423 b_first_row=b_first_row, &
2424 c_first_col=c_first_col, &
2425 c_first_row=c_first_row)
2426 CALL cp_fm_gemm(transa, transb, m, n, k, -alpha, a_im, b_im, 1.0_dp, c_re, &
2427 a_first_col=a_first_col, &
2428 a_first_row=a_first_row, &
2429 b_first_col=b_first_col, &
2430 b_first_row=b_first_row, &
2431 c_first_col=c_first_col, &
2432 c_first_row=c_first_row)
2433 CALL cp_fm_gemm(transa, transb, m, n, k, alpha, a_re, b_im, beta, c_im, &
2434 a_first_col=a_first_col, &
2435 a_first_row=a_first_row, &
2436 b_first_col=b_first_col, &
2437 b_first_row=b_first_row, &
2438 c_first_col=c_first_col, &
2439 c_first_row=c_first_row)
2440 CALL cp_fm_gemm(transa, transb, m, n, k, alpha, a_im, b_re, 1.0_dp, c_im, &
2441 a_first_col=a_first_col, &
2442 a_first_row=a_first_row, &
2443 b_first_col=b_first_col, &
2444 b_first_row=b_first_row, &
2445 c_first_col=c_first_col, &
2446 c_first_row=c_first_row)
2448 CALL timestop(handle)
2459 SUBROUTINE cp_fm_lu_invert(matrix, info_out)
2461 INTEGER,
INTENT(OUT),
OPTIONAL :: info_out
2463 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_lu_invert'
2465 INTEGER :: nrows_global, handle, info, lwork
2466 INTEGER,
DIMENSION(:),
ALLOCATABLE :: ipivot
2467 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: mat
2468 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: mat_sp
2469 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: work
2470 REAL(kind=
sp),
DIMENSION(:),
ALLOCATABLE :: work_sp
2471#if defined(__parallel)
2473 INTEGER,
DIMENSION(9) :: desca
2474 INTEGER,
DIMENSION(:),
ALLOCATABLE :: iwork
2479 CALL timeset(routinen, handle)
2481 mat => matrix%local_data
2482 mat_sp => matrix%local_data_sp
2483 nrows_global = matrix%matrix_struct%nrow_global
2484 cpassert(nrows_global .EQ. matrix%matrix_struct%ncol_global)
2485 ALLOCATE (ipivot(nrows_global))
2487#if defined(__parallel)
2488 desca = matrix%matrix_struct%descriptor
2489 IF (matrix%use_sp)
THEN
2490 CALL psgetrf(nrows_global, nrows_global, &
2491 mat_sp, 1, 1, desca, ipivot, info)
2493 CALL pdgetrf(nrows_global, nrows_global, &
2494 mat, 1, 1, desca, ipivot, info)
2498 IF (matrix%use_sp)
THEN
2499 CALL sgetrf(nrows_global, nrows_global, &
2500 mat_sp, lda, ipivot, info)
2502 CALL dgetrf(nrows_global, nrows_global, &
2503 mat, lda, ipivot, info)
2507 CALL cp_abort(__location__,
"LU decomposition has failed")
2510 IF (matrix%use_sp)
THEN
2513 ALLOCATE (work_sp(1))
2515#if defined(__parallel)
2517 IF (matrix%use_sp)
THEN
2518 CALL psgetri(nrows_global, mat_sp, 1, 1, desca, &
2519 ipivot, work_sp, -1, iwork, -1, info)
2520 lwork = int(work_sp(1))
2521 DEALLOCATE (work_sp)
2522 ALLOCATE (work_sp(lwork))
2524 CALL pdgetri(nrows_global, mat, 1, 1, desca, &
2525 ipivot, work, -1, iwork, -1, info)
2526 lwork = int(work(1))
2528 ALLOCATE (work(lwork))
2530 liwork = int(iwork(1))
2532 ALLOCATE (iwork(liwork))
2533 IF (matrix%use_sp)
THEN
2534 CALL psgetri(nrows_global, mat_sp, 1, 1, desca, &
2535 ipivot, work_sp, lwork, iwork, liwork, info)
2537 CALL pdgetri(nrows_global, mat, 1, 1, desca, &
2538 ipivot, work, lwork, iwork, liwork, info)
2542 IF (matrix%use_sp)
THEN
2543 CALL sgetri(nrows_global, mat_sp, lda, &
2544 ipivot, work_sp, -1, info)
2545 lwork = int(work_sp(1))
2546 DEALLOCATE (work_sp)
2547 ALLOCATE (work_sp(lwork))
2548 CALL sgetri(nrows_global, mat_sp, lda, &
2549 ipivot, work_sp, lwork, info)
2551 CALL dgetri(nrows_global, mat, lda, &
2552 ipivot, work, -1, info)
2553 lwork = int(work(1))
2555 ALLOCATE (work(lwork))
2556 CALL dgetri(nrows_global, mat, lda, &
2557 ipivot, work, lwork, info)
2560 IF (matrix%use_sp)
THEN
2561 DEALLOCATE (work_sp)
2567 IF (
PRESENT(info_out))
THEN
2571 CALL cp_abort(__location__,
"LU inversion has failed")
2574 CALL timestop(handle)
2576 END SUBROUTINE cp_fm_lu_invert
2590 CHARACTER,
INTENT(IN) :: mode
2591 REAL(kind=
dp) :: res
2593 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_norm'
2595 INTEGER :: nrows, ncols, handle, lwork, nrows_local, ncols_local
2596 REAL(kind=
sp) :: res_sp
2597 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: aa
2598 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: aa_sp
2599 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: work
2600 REAL(kind=
sp),
DIMENSION(:),
ALLOCATABLE :: work_sp
2601#if defined(__parallel)
2602 INTEGER,
DIMENSION(9) :: desca
2607 CALL timeset(routinen, handle)
2610 nrow_global=nrows, &
2611 ncol_global=ncols, &
2612 nrow_local=nrows_local, &
2613 ncol_local=ncols_local)
2614 aa => matrix%local_data
2615 aa_sp => matrix%local_data_sp
2617#if defined(__parallel)
2618 desca = matrix%matrix_struct%descriptor
2622 CASE (
'1',
'O',
'o')
2626 CASE (
'F',
'f',
'E',
'e')
2629 cpabort(
"mode input is not valid")
2631 IF (matrix%use_sp)
THEN
2632 ALLOCATE (work_sp(lwork))
2633 res_sp = pslange(mode, nrows, ncols, aa_sp, 1, 1, desca, work_sp)
2634 DEALLOCATE (work_sp)
2635 res = real(res_sp, kind=
dp)
2637 ALLOCATE (work(lwork))
2638 res = pdlange(mode, nrows, ncols, aa, 1, 1, desca, work)
2645 CASE (
'1',
'O',
'o')
2649 CASE (
'F',
'f',
'E',
'e')
2652 cpabort(
"mode input is not valid")
2654 IF (matrix%use_sp)
THEN
2655 ALLOCATE (work_sp(lwork))
2656 lda =
SIZE(aa_sp, 1)
2657 res_sp = slange(mode, nrows, ncols, aa_sp, lda, work_sp)
2658 DEALLOCATE (work_sp)
2659 res = real(res_sp, kind=
dp)
2661 ALLOCATE (work(lwork))
2663 res = dlange(mode, nrows, ncols, aa, lda, work)
2668 CALL timestop(handle)
2678 FUNCTION cp_fm_latra(matrix)
RESULT(res)
2680 REAL(kind=
dp) :: res
2682 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_latra'
2684 INTEGER :: nrows, ncols, handle
2685 REAL(kind=
sp) :: res_sp
2686 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: aa
2687 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: aa_sp
2688#if defined(__parallel)
2689 INTEGER,
DIMENSION(9) :: desca
2694 CALL timeset(routinen, handle)
2696 nrows = matrix%matrix_struct%nrow_global
2697 ncols = matrix%matrix_struct%ncol_global
2698 cpassert(nrows .EQ. ncols)
2699 aa => matrix%local_data
2700 aa_sp => matrix%local_data_sp
2702#if defined(__parallel)
2703 desca = matrix%matrix_struct%descriptor
2704 IF (matrix%use_sp)
THEN
2705 res_sp = pslatra(nrows, aa_sp, 1, 1, desca)
2706 res = real(res_sp, kind=
dp)
2708 res = pdlatra(nrows, aa, 1, 1, desca)
2711 IF (matrix%use_sp)
THEN
2714 res_sp = res_sp + aa_sp(ii, ii)
2716 res = real(res_sp, kind=
dp)
2720 res = res + aa(ii, ii)
2725 CALL timestop(handle)
2727 END FUNCTION cp_fm_latra
2743 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tau
2744 INTEGER,
INTENT(IN) :: nrow, ncol, first_row, first_col
2746 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_pdgeqpf'
2749 INTEGER :: info, lwork
2750 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipiv
2751 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2752 REAL(kind=
dp),
DIMENSION(:),
POINTER :: work
2753#if defined(__parallel)
2754 INTEGER,
DIMENSION(9) :: descc
2759 CALL timeset(routinen, handle)
2761 a => matrix%local_data
2763 ALLOCATE (work(2*nrow))
2764 ALLOCATE (ipiv(ncol))
2767#if defined(__parallel)
2768 descc(:) = matrix%matrix_struct%descriptor(:)
2770 CALL pdgeqpf(nrow, ncol, a, first_row, first_col, descc, ipiv, tau, work, lwork, info)
2771 lwork = int(work(1))
2773 ALLOCATE (work(lwork))
2778 CALL pdgeqpf(nrow, ncol, a, first_row, first_col, descc, ipiv, tau, work, lwork, info)
2780 cpassert(first_row == 1 .AND. first_col == 1)
2782 CALL dgeqp3(nrow, ncol, a, lda, ipiv, tau, work, lwork, info)
2783 lwork = int(work(1))
2785 ALLOCATE (work(lwork))
2788 CALL dgeqp3(nrow, ncol, a, lda, ipiv, tau, work, lwork, info)
2795 CALL timestop(handle)
2815 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tau
2816 INTEGER,
INTENT(IN) :: nrow, first_row, first_col
2818 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_pdorgqr'
2821 INTEGER :: info, lwork
2822 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2823 REAL(kind=
dp),
DIMENSION(:),
POINTER :: work
2824#if defined(__parallel)
2825 INTEGER,
DIMENSION(9) :: descc
2830 CALL timeset(routinen, handle)
2832 a => matrix%local_data
2834 ALLOCATE (work(2*nrow))
2837#if defined(__parallel)
2838 descc(:) = matrix%matrix_struct%descriptor(:)
2840 CALL pdorgqr(nrow, nrow, nrow, a, first_row, first_col, descc, tau, work, lwork, info)
2842 lwork = int(work(1))
2844 ALLOCATE (work(lwork))
2847 CALL pdorgqr(nrow, nrow, nrow, a, first_row, first_col, descc, tau, work, lwork, info)
2849 cpassert(first_row == 1 .AND. first_col == 1)
2851 CALL dorgqr(nrow, nrow, nrow, a, lda, tau, work, lwork, info)
2852 lwork = int(work(1))
2854 ALLOCATE (work(lwork))
2855 CALL dorgqr(nrow, nrow, nrow, a, lda, tau, work, lwork, info)
2860 CALL timestop(handle)
2875 INTEGER,
INTENT(IN) :: irow, jrow
2876 REAL(
dp),
INTENT(IN) :: cs, sn
2878 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_rot_rows'
2879 INTEGER :: handle, ncol
2881#if defined(__parallel)
2882 INTEGER :: info, lwork
2883 INTEGER,
DIMENSION(9) :: desc
2884 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
2886 CALL timeset(routinen, handle)
2888#if defined(__parallel)
2889 IF (1 /= matrix%matrix_struct%context%n_pid)
THEN
2891 ALLOCATE (work(lwork))
2892 desc(:) = matrix%matrix_struct%descriptor(:)
2894 matrix%local_data(1, 1), irow, 1, desc, ncol, &
2895 matrix%local_data(1, 1), jrow, 1, desc, ncol, &
2896 cs, sn, work, lwork, info)
2901 CALL drot(ncol, matrix%local_data(irow, 1), ncol, matrix%local_data(jrow, 1), ncol, cs, sn)
2902#if defined(__parallel)
2905 CALL timestop(handle)
2919 INTEGER,
INTENT(IN) :: icol, jcol
2920 REAL(
dp),
INTENT(IN) :: cs, sn
2922 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_rot_cols'
2923 INTEGER :: handle, nrow
2925#if defined(__parallel)
2926 INTEGER :: info, lwork
2927 INTEGER,
DIMENSION(9) :: desc
2928 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
2930 CALL timeset(routinen, handle)
2932#if defined(__parallel)
2933 IF (1 /= matrix%matrix_struct%context%n_pid)
THEN
2935 ALLOCATE (work(lwork))
2936 desc(:) = matrix%matrix_struct%descriptor(:)
2938 matrix%local_data(1, 1), 1, icol, desc, 1, &
2939 matrix%local_data(1, 1), 1, jcol, desc, 1, &
2940 cs, sn, work, lwork, info)
2945 CALL drot(nrow, matrix%local_data(1, icol), 1, matrix%local_data(1, jcol), 1, cs, sn)
2946#if defined(__parallel)
2949 CALL timestop(handle)
2967 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: b
2968 INTEGER,
INTENT(IN),
OPTIONAL :: nrows, ncols, start_row, start_col
2969 LOGICAL,
INTENT(IN),
OPTIONAL :: do_norm, do_print
2971 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_fm_Gram_Schmidt_orthonorm'
2973 INTEGER :: end_col_global, end_col_local, end_row_global, end_row_local, handle, i, j, &
2974 j_col, ncol_global, ncol_local, nrow_global, nrow_local, start_col_global, &
2975 start_col_local, start_row_global, start_row_local, this_col, unit_nr
2976 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2977 LOGICAL :: my_do_norm, my_do_print
2978 REAL(kind=
dp) :: norm
2979 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
2981 CALL timeset(routinen, handle)
2984 IF (
PRESENT(do_norm)) my_do_norm = do_norm
2986 my_do_print = .false.
2987 IF (
PRESENT(do_print) .AND. (my_do_norm)) my_do_print = do_print
2990 IF (my_do_print)
THEN
2992 IF (unit_nr < 1) my_do_print = .false.
2995 IF (
SIZE(b) /= 0)
THEN
2996 IF (
PRESENT(nrows))
THEN
2999 nrow_global =
SIZE(b, 1)
3002 IF (
PRESENT(ncols))
THEN
3005 ncol_global =
SIZE(b, 2)
3008 IF (
PRESENT(start_row))
THEN
3009 start_row_global = start_row
3011 start_row_global = 1
3014 IF (
PRESENT(start_col))
THEN
3015 start_col_global = start_col
3017 start_col_global = 1
3020 end_row_global = start_row_global + nrow_global - 1
3021 end_col_global = start_col_global + ncol_global - 1
3024 nrow_global=nrow_global, ncol_global=ncol_global, &
3025 nrow_local=nrow_local, ncol_local=ncol_local, &
3026 row_indices=row_indices, col_indices=col_indices)
3027 IF (end_row_global > nrow_global)
THEN
3028 end_row_global = nrow_global
3030 IF (end_col_global > ncol_global)
THEN
3031 end_col_global = ncol_global
3038 DO start_row_local = 1, nrow_local
3039 IF (row_indices(start_row_local) >= start_row_global)
EXIT
3042 DO end_row_local = start_row_local, nrow_local
3043 IF (row_indices(end_row_local) > end_row_global)
EXIT
3045 end_row_local = end_row_local - 1
3047 DO start_col_local = 1, ncol_local
3048 IF (col_indices(start_col_local) >= start_col_global)
EXIT
3051 DO end_col_local = start_col_local, ncol_local
3052 IF (col_indices(end_col_local) > end_col_global)
EXIT
3054 end_col_local = end_col_local - 1
3056 a => matrix_a%local_data
3058 this_col = col_indices(start_col_local) - start_col_global + 1
3060 b(:, this_col) = a(:, start_col_local)
3062 IF (my_do_norm)
THEN
3064 b(:, this_col) = b(:, this_col)/norm
3065 IF (my_do_print)
WRITE (unit_nr,
'(I3,F8.3)') this_col, norm
3068 DO i = start_col_local + 1, end_col_local
3069 this_col = col_indices(i) - start_col_global + 1
3070 b(:, this_col) = a(:, i)
3071 DO j = start_col_local, i - 1
3072 j_col = col_indices(j) - start_col_global + 1
3073 b(:, this_col) = b(:, this_col) - &
3078 IF (my_do_norm)
THEN
3080 b(:, this_col) = b(:, this_col)/norm
3081 IF (my_do_print)
WRITE (unit_nr,
'(I3,F8.3)') this_col, norm
3085 CALL matrix_a%matrix_struct%para_env%sum(b)
3088 CALL timestop(handle)
3100 INTEGER,
INTENT(IN) :: n
3101 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
3105 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
3106 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
3107#if defined(__parallel)
3108 INTEGER,
DIMENSION(9) :: desca
3112 IF (
PRESENT(uplo)) myuplo = uplo
3114 a => fm_matrix%local_data
3115 a_sp => fm_matrix%local_data_sp
3116#if defined(__parallel)
3117 desca(:) = fm_matrix%matrix_struct%descriptor(:)
3118 IF (fm_matrix%use_sp)
THEN
3119 CALL pspotrf(myuplo, n, a_sp(1, 1), 1, 1, desca, info)
3121 CALL pdpotrf(myuplo, n, a(1, 1), 1, 1, desca, info)
3124 IF (fm_matrix%use_sp)
THEN
3125 CALL spotrf(myuplo, n, a_sp(1, 1),
SIZE(a_sp, 1), info)
3127 CALL dpotrf(myuplo, n, a(1, 1),
SIZE(a, 1), info)
3131 cpabort(
"Cholesky decomposition failed. Matrix ill-conditioned?")
3143 INTEGER,
INTENT(IN) :: n
3144 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
3147 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a
3148 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: a_sp
3150#if defined(__parallel)
3151 INTEGER,
DIMENSION(9) :: desca
3155 IF (
PRESENT(uplo)) myuplo = uplo
3157 a => fm_matrix%local_data
3158 a_sp => fm_matrix%local_data_sp
3159#if defined(__parallel)
3160 desca(:) = fm_matrix%matrix_struct%descriptor(:)
3161 IF (fm_matrix%use_sp)
THEN
3162 CALL pspotri(myuplo, n, a_sp(1, 1), 1, 1, desca, info)
3164 CALL pdpotri(myuplo, n, a(1, 1), 1, 1, desca, info)
3167 IF (fm_matrix%use_sp)
THEN
3168 CALL spotri(myuplo, n, a_sp(1, 1),
SIZE(a_sp, 1), info)
3170 CALL dpotri(myuplo, n, a(1, 1),
SIZE(a, 1), info)
3186 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: xv
3187 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: yv
3188 REAL(kind=
dp),
OPTIONAL,
INTENT(IN) :: alpha, beta
3190 INTEGER :: na, nc, nx, ny
3191 REAL(kind=
dp) :: aval, bval
3192#if defined(__parallel)
3193 INTEGER :: nrl, ncl, ic, ir
3194 INTEGER,
DIMENSION(:),
POINTER :: rind, cind
3195 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: xvl, yvl, yvm
3198 IF (amat%use_sp)
THEN
3199 cpabort(
"cp_fm_matvec: SP option not available")
3202 IF (
PRESENT(alpha)) aval = alpha
3204 IF (
PRESENT(beta)) bval = beta
3209 IF ((nx /= ny) .OR. (nc /= nx))
THEN
3210 cpabort(
"cp_fm_matvec: incompatible dimensions")
3212#if defined(__parallel)
3214 row_indices=rind, col_indices=cind)
3215 ALLOCATE (xvl(ncl), yvl(nrl), yvm(ny))
3217 xvl(ic) = xv(cind(ic))
3219 yvl(1:nrl) = matmul(amat%local_data, xvl(1:ncl))
3222 yvm(rind(ir)) = yvl(ir)
3224 CALL amat%matrix_struct%para_env%sum(yvm)
3225 IF (bval == 0.0_dp)
THEN
3228 yv = bval*yv + aval*yvm
3231 IF (bval == 0.0_dp)
THEN
3232 yv = aval*matmul(amat%local_data, xv)
3234 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_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_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
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
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