LCOV - code coverage report
Current view: top level - diagonalization - nvlamath.F90 (source / functions) Coverage Total Hit
Test: FLEUR test coverage Lines: 26.5 % 34 9
Test Date: 2026-03-18 04:40:43 Functions: 66.7 % 3 2

            Line data    Source code
       1              : !--------------------------------------------------------------------------------
       2              : ! Copyright (c) 2024 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
       3              : ! This file is part of FLEUR and available as free software under the conditions
       4              : ! of the MIT license as expressed in the LICENSE file in more detail.
       5              : !--------------------------------------------------------------------------------
       6              : module m_nvlamath
       7              :    use m_types_solver
       8              :    use m_types_mat
       9              :    use m_judft
      10              : #ifdef CPP_GPU_NVLAMATH      
      11              :    use nvlamath
      12              : #endif
      13              :    implicit none
      14              :    private
      15              :    type, extends(t_solver)::t_solver_nvlamath
      16              :    contains
      17              :       !procedure        :: solve_std_dp => nvlamath_diag  !solver for standard eigenvalue problem
      18              :       !procedure        :: solve_std_sp => nvlamath_diag_sp  !solver for standard eigenvalue problem
      19              :       procedure        :: solve_gev => nvlamath_gev  !solver for generalized eigenvalue problem
      20              :       !procedure        :: to_std => nvlamath_reduction     !transform the H of the generalized problem to a std problem
      21              :       !procedure        :: backtrans => nvlamath_recover  !transform the Eigenvalue back to the generalized problem
      22              :    end type
      23              :    public :: t_solver_nvlamath, get_solver_nvlamath
      24              : 
      25              : contains
      26              : 
      27           97 :    function get_solver_nvlamath() result(solver)
      28              :       type(t_solver_nvlamath), pointer::solver
      29           97 :       allocate (solver)
      30           97 :       solver%name = "nvlamath"
      31              : #ifdef CPP_GPU_NVLAMATH      
      32              :       solver%available = .true.
      33              : #else
      34           97 :       solver%available = .false.
      35              : #endif      
      36           97 :       solver%serial = .true.
      37           97 :       solver%generalized = .true.
      38           97 :       solver%GPU = .true.
      39           97 :    end function
      40              : 
      41            0 :    subroutine nvlamath_gev(self, hmat, smat, ne, eig, zmat, ikpt)
      42              :       !Simple driver to solve Generalized Eigenvalue Problem using nvlamath routine
      43              :       implicit none
      44              :       class(t_solver_nvlamath)            :: self
      45              :       class(t_mat), intent(INOUT)  :: hmat, smat
      46              :       integer, intent(INOUT)      :: ne
      47              :       class(t_mat), allocatable, intent(OUT)    :: zmat
      48              :       real, intent(OUT)           :: eig(:)
      49              :       integer, intent(IN)         :: ikpt
      50              : 
      51              :       integer            :: lwork, info, m
      52            0 :       integer, allocatable:: ifail(:), iwork(:)
      53            0 :       complex, allocatable:: work(:)
      54            0 :       real, allocatable   :: rwork(:)
      55              :       real               :: dumrwork(1), abstol
      56              :       complex            :: dumwork(1)
      57              :       real, external      :: dlamch
      58            0 :       real               :: eigTemp(hmat%matsize1)
      59              : 
      60            0 :       allocate (t_mat::zmat)
      61            0 :       call zmat%alloc(hmat%l_real, hmat%matsize1, ne)
      62            0 :       abstol = 2*dlamch('S')
      63            0 :       if (hmat%l_real) then
      64            0 :          allocate (iwork(5*hmat%matsize1), ifail(hmat%matsize1))
      65              :          !$acc data create(iwork,ifail,eigTemp,zmat%data_r)
      66              :          !$acc host_data use_device(hmat%data_r,smat%data_r,eigTemp,zmat%data_r,dumrwork,iwork,ifail)
      67              :          call dsygvx(1, 'V', 'I', 'U', hmat%matsize1, hmat%data_r, size(hmat%data_r, 1), smat%data_r, size(smat%data_r, 1), &
      68            0 :                      0.0, 0.0, 1, ne, abstol, m, eigTemp, zmat%data_r, size(zmat%data_r, 1), dumrwork, -1, iwork, ifail, info)
      69              :          !$acc end host_data
      70              :          !$acc update self(dumrwork)             
      71            0 :          lwork = dumrwork(1)
      72            0 :          allocate (rwork(lwork))
      73              :          !$acc data create(rwork)
      74            0 :          if (info .ne. 0) call judft_error("Diagonalization via nvlamath failed (Workspace)", no=info)
      75              :          !$acc host_data use_device(hmat%data_r,smat%data_r,eigTemp,zmat%data_r,rwork,iwork,ifail)
      76              :          call dsygvx(1, 'V', 'I', 'U', hmat%matsize1, hmat%data_r, size(hmat%data_r, 1), smat%data_r, size(smat%data_r, 1), &
      77            0 :                      0.0, 0.0, 1, ne, abstol, m, eigTemp, zmat%data_r, size(zmat%data_r, 1), rwork, lwork, iwork, ifail, info)
      78              :          !$acc end host_data
      79              :          !$acc end data
      80              :          !$acc update self(eigTemp,zmat%data_r)            
      81              :          !$acc end data            
      82              :       else
      83              :         
      84            0 :          allocate (rwork(7*hmat%matsize1), iwork(5*hmat%matsize1), ifail(hmat%matsize1))
      85              :          !$acc data create(iwork,ifail,eigTemp,zmat%data_c,rwork)
      86              :          !Do a workspace query
      87              :          !$acc host_data use_device(hmat%data_c,smat%data_c,eigTemp,zmat%data_c,dumwork,rwork,iwork,ifail)
      88              :          
      89              :          call zhegvx(1, 'V', 'I', 'U', hmat%matsize1, hmat%data_c, size(hmat%data_c, 1), smat%data_c, size(smat%data_c, 1), &
      90            0 :                      0.0, 0.0, 1, ne, abstol, m, eigTemp, zmat%data_c, size(zmat%data_c, 1), dumwork, -1, rwork, iwork, ifail, info)
      91              :          !$acc end host_data
      92              :          !$acc update self(dumwork)
      93            0 :          lwork = dumwork(1)
      94            0 :          allocate (work(lwork))
      95              :          !$acc data create(work)
      96            0 :          if (info .ne. 0) call judft_error("Diagonalization via nvlamath failed (Workspace)", no=info)
      97              :          !Perform diagonalization
      98              :          !$acc host_data use_device(hmat%data_c,smat%data_c,eigTemp,zmat%data_c,work,rwork,iwork,ifail)
      99              :          call zhegvx(1, 'V', 'I', 'U', hmat%matsize1, hmat%data_c, size(hmat%data_c, 1), smat%data_c, size(smat%data_c, 1), &
     100            0 :                       0.0, 0.0, 1, ne, abstol, m, eigTemp, zmat%data_c, size(zmat%data_c, 1), work, lwork, rwork, iwork, ifail, info)
     101              :          !$acc end host_data
     102              :          !$acc end data
     103              :          !$acc update self(eigTemp,zmat%data_c)            
     104              :          !$acc end data
     105              :       end if
     106            0 :       eig(:min(size(eig), size(eigTemp))) = eigTemp(:min(size(eig), size(eigTemp)))
     107            0 :       if (info .ne. 0) call judft_error("Diagonalization via nvlamath failed(zhegvx/dsygvx)", no=info)
     108            0 :       if (m .ne. ne) call judft_error("Diagonalization via nvlamath failed failed without explicit errorcode.")
     109            0 :    end subroutine nvlamath_gev
     110              : 
     111           97 : end module m_nvlamath
        

Generated by: LCOV version 2.0-1