LCOV - code coverage report
Current view: top level - src/fm - cp_cfm_cholesky.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:32ddf85) Lines: 27 32 84.4 %
Date: 2025-05-17 08:08:58 Functions: 2 2 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief various cholesky decomposition related routines
      10             : !> \par History
      11             : !>      12.2002 Moved routines from cp_cfm_basic_linalg to this new module [Rocco Meli]
      12             : ! **************************************************************************************************
      13             : MODULE cp_cfm_cholesky
      14             :    USE cp_cfm_types, ONLY: cp_cfm_type
      15             :    USE kinds, ONLY: dp
      16             : #if defined(__DLAF)
      17             :    USE cp_cfm_dlaf_api, ONLY: cp_cfm_pzpotrf_dlaf
      18             :    USE cp_dlaf_utils_api, ONLY: cp_dlaf_initialize, cp_dlaf_create_grid
      19             :    USE cp_fm_cholesky, ONLY: cholesky_type, dlaf_cholesky_n_min, FM_CHOLESKY_TYPE_DLAF
      20             : #endif
      21             : 
      22             : #include "../base/base_uses.f90"
      23             : 
      24             :    IMPLICIT NONE
      25             :    PRIVATE
      26             : 
      27             :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
      28             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_cfm_cholesky'
      29             : 
      30             :    PUBLIC :: cp_cfm_cholesky_decompose, &
      31             :              cp_cfm_cholesky_invert
      32             : 
      33             : ! **************************************************************************************************
      34             : 
      35             : CONTAINS
      36             : 
      37             : ! **************************************************************************************************
      38             : !> \brief Used to replace a symmetric positive definite matrix M with its Cholesky
      39             : !>      decomposition U: M = U^T * U, with U upper triangular.
      40             : !> \param matrix   the matrix to replace with its Cholesky decomposition
      41             : !> \param n        the number of row (and columns) of the matrix &
      42             : !>                 (defaults to the min(size(matrix)))
      43             : !> \param info_out if present, outputs info from (p)zpotrf
      44             : !> \par History
      45             : !>      05.2002 created [JVdV]
      46             : !>      12.2002 updated, added n optional parm [fawzi]
      47             : !>      09.2021 removed CPASSERT(info == 0) since there is already check of info [Jan Wilhelm]
      48             : !>      12.2024 Added DLA-Future support [Rocco Meli]
      49             : !>      03.2025 Moved DLA-Future support to cp_cfm_cholesky_decompose_dlaf [Rocco Meli]
      50             : !> \author Joost
      51             : ! **************************************************************************************************
      52       20994 :    SUBROUTINE cp_cfm_cholesky_decompose(matrix, n, info_out)
      53             :       TYPE(cp_cfm_type), INTENT(IN)                      :: matrix
      54             :       INTEGER, INTENT(in), OPTIONAL                      :: n
      55             :       INTEGER, INTENT(out), OPTIONAL                     :: info_out
      56             : 
      57             :       CHARACTER(len=*), PARAMETER :: routineN = 'cp_cfm_cholesky_decompose'
      58             : 
      59       20994 :       COMPLEX(kind=dp), DIMENSION(:, :), POINTER         :: a
      60             :       INTEGER                                            :: handle, info, my_n
      61             : #if defined(__parallel)
      62             :       INTEGER, DIMENSION(9)                              :: desca
      63             : #else
      64             :       INTEGER                                            :: lda
      65             : #endif
      66             : 
      67       20994 :       CALL timeset(routineN, handle)
      68             : 
      69             :       my_n = MIN(matrix%matrix_struct%nrow_global, &
      70       20994 :                  matrix%matrix_struct%ncol_global)
      71       20994 :       IF (PRESENT(n)) THEN
      72        4506 :          CPASSERT(n <= my_n)
      73        4506 :          my_n = n
      74             :       END IF
      75             : 
      76       20994 :       a => matrix%local_data
      77             : 
      78             : #if defined(__parallel)
      79      209940 :       desca(:) = matrix%matrix_struct%descriptor(:)
      80             : #if defined(__DLAF)
      81             :       IF (cholesky_type == FM_CHOLESKY_TYPE_DLAF .AND. matrix%matrix_struct%nrow_global .GE. dlaf_cholesky_n_min) THEN
      82             :          ! Initialize DLA-Future on-demand; if already initialized, does nothing
      83             :          CALL cp_dlaf_initialize()
      84             : 
      85             :          ! Create DLAF grid from BLACS context; if already present, does nothing
      86             :          CALL cp_dlaf_create_grid(matrix%matrix_struct%context%get_handle())
      87             : 
      88             :          CALL cp_cfm_pzpotrf_dlaf('U', my_n, a(:, :), 1, 1, desca, info)
      89             :       ELSE
      90             : #endif
      91       20994 :          CALL pzpotrf('U', my_n, a(1, 1), 1, 1, desca, info)
      92             : #if defined(__DLAF)
      93             :       END IF
      94             : #endif
      95             : 
      96             : #else
      97             :       lda = SIZE(a, 1)
      98             :       CALL zpotrf('U', my_n, a(1, 1), lda, info)
      99             : #endif
     100             : 
     101       20994 :       IF (PRESENT(info_out)) THEN
     102        4506 :          info_out = info
     103             :       ELSE
     104       16488 :          IF (info /= 0) &
     105             :             CALL cp_abort(__LOCATION__, &
     106           0 :                           "Cholesky decompose failed: matrix is not positive definite or ill-conditioned")
     107             :       END IF
     108             : 
     109       20994 :       CALL timestop(handle)
     110             : 
     111       20994 :    END SUBROUTINE cp_cfm_cholesky_decompose
     112             : 
     113             : ! **************************************************************************************************
     114             : !> \brief Used to replace Cholesky decomposition by the inverse.
     115             : !> \param matrix : the matrix to invert (must be an upper triangular matrix),
     116             : !>                 and is the output of Cholesky decomposition
     117             : !> \param n : size of the matrix to invert (defaults to the min(size(matrix)))
     118             : !> \param info_out : if present, outputs info of (p)zpotri
     119             : !> \par History
     120             : !>      05.2002 created Lianheng Tong, based on cp_fm_cholesky_invert
     121             : !> \author Lianheng Tong
     122             : ! **************************************************************************************************
     123        4602 :    SUBROUTINE cp_cfm_cholesky_invert(matrix, n, info_out)
     124             :       TYPE(cp_cfm_type), INTENT(IN)              :: matrix
     125             :       INTEGER, INTENT(in), OPTIONAL              :: n
     126             :       INTEGER, INTENT(out), OPTIONAL             :: info_out
     127             : 
     128             :       CHARACTER(len=*), PARAMETER :: routineN = 'cp_cfm_cholesky_invert'
     129        4602 :       COMPLEX(kind=dp), DIMENSION(:, :), POINTER :: aa
     130             :       INTEGER                                    :: info, handle
     131             :       INTEGER                                    :: my_n
     132             : #if defined(__parallel)
     133             :       INTEGER, DIMENSION(9)                      :: desca
     134             : #endif
     135             : 
     136        4602 :       CALL timeset(routineN, handle)
     137             : 
     138             :       my_n = MIN(matrix%matrix_struct%nrow_global, &
     139        4602 :                  matrix%matrix_struct%ncol_global)
     140        4602 :       IF (PRESENT(n)) THEN
     141           0 :          CPASSERT(n <= my_n)
     142           0 :          my_n = n
     143             :       END IF
     144             : 
     145        4602 :       aa => matrix%local_data
     146             : 
     147             : #if defined(__parallel)
     148       46020 :       desca = matrix%matrix_struct%descriptor
     149        4602 :       CALL pzpotri('U', my_n, aa(1, 1), 1, 1, desca, info)
     150             : #else
     151             :       CALL zpotri('U', my_n, aa(1, 1), SIZE(aa, 1), info)
     152             : #endif
     153             : 
     154        4602 :       IF (PRESENT(info_out)) THEN
     155           0 :          info_out = info
     156             :       ELSE
     157        4602 :          IF (info /= 0) &
     158             :             CALL cp_abort(__LOCATION__, &
     159           0 :                           "Cholesky invert failed: the matrix is not positive definite or ill-conditioned.")
     160             :       END IF
     161             : 
     162        4602 :       CALL timestop(handle)
     163             : 
     164        4602 :    END SUBROUTINE cp_cfm_cholesky_invert
     165             : 
     166             : END MODULE cp_cfm_cholesky

Generated by: LCOV version 1.15