LCOV - code coverage report
Current view: top level - src/48_diago - m_lobpcg2_cprj.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 78.8 % 405 319
Test Date: 2026-11-10 11:05:29 Functions: 69.2 % 13 9
Branches: 51.2 % 168 86

             Branch data     Line data    Source code
       1                 :             : 
       2                 :             : #if defined HAVE_CONFIG_H
       3                 :             : #include "config.h"
       4                 :             : #endif
       5                 :             : 
       6                 :             : #include "abi_common.h"
       7                 :             : 
       8                 :             : module m_lobpcg2_cprj
       9                 :             : 
      10                 :             :   use defs_basis
      11                 :             :   use m_xg
      12                 :             :   use m_xg_nonlop
      13                 :             :   use m_xg_ortho_RR
      14                 :             :   use m_xgTransposer
      15                 :             :   use m_xgScalapack
      16                 :             :   use defs_basis
      17                 :             :   use m_abicore
      18                 :             :   use m_errors
      19                 :             :   use m_xomp
      20                 :             : #ifdef HAVE_OPENMP
      21                 :             :   use omp_lib
      22                 :             : #endif
      23                 :             : 
      24                 :             :   use m_xmpi
      25                 :             :   use m_time, only : timab
      26                 :             : 
      27                 :             :   implicit none
      28                 :             : 
      29                 :             :   private
      30                 :             : 
      31                 :             :   integer, parameter :: tim_init     = 2040
      32                 :             :   integer, parameter :: tim_free     = 2041
      33                 :             :   integer, parameter :: tim_cprj     = 2043
      34                 :             :   integer, parameter :: tim_ortho    = 2044
      35                 :             :   integer, parameter :: tim_transpose = 2039
      36                 :             :   integer, parameter :: tim_maxres   = 2046
      37                 :             :   integer, parameter :: tim_ax_k     = 2048
      38                 :             :   integer, parameter :: tim_ax_v     = 2049
      39                 :             :   integer, parameter :: tim_ax_nl    = 2050
      40                 :             :   integer, parameter :: tim_pcond    = 2047
      41                 :             : 
      42                 :             :   integer, parameter :: tim_Bortho_X    = 2031
      43                 :             :   integer, parameter :: tim_Bortho_XW   = 2032
      44                 :             :   integer, parameter :: tim_Bortho_XWP  = 2033
      45                 :             :   integer, parameter :: tim_Bortho_Xall = 2034
      46                 :             :   integer, parameter :: tim_RR_X        = 2035
      47                 :             :   integer, parameter :: tim_RR_XW       = 2036
      48                 :             :   integer, parameter :: tim_RR_XWP      = 2037
      49                 :             :   integer, parameter :: tim_RR_Xall     = 2038
      50                 :             : 
      51                 :             :   integer, parameter :: tim_copy     = 2042
      52                 :             :   integer, parameter :: tim_nbdbuf   = 2045
      53                 :             : 
      54                 :             :   integer, parameter :: tim_enl = 2051
      55                 :             : 
      56                 :             :   type, public :: lobpcg_t
      57                 :             :     logical :: is_nested                     ! For OpenMP nested region
      58                 :             :     integer :: spacedim                      ! Space dimension for one vector (WFs)
      59                 :             :     integer :: space                         ! Space type for one vector
      60                 :             :     integer :: space_cprj                    ! Space type for one projector
      61                 :             :     integer :: cprjdim                       ! Space dimension for one vector (cprj)
      62                 :             :     integer :: neigenpairs                   ! Number of eigen values/vectors we want
      63                 :             :     integer :: nblock                        ! Number of block in the space of dim spacedim
      64                 :             :     integer :: blockdim                      ! Number of vectors in one block
      65                 :             :     integer :: blockdim_cprj                 ! Number of vectors in one block (for cprj array)
      66                 :             :     integer :: nline                         ! Number of line to perform
      67                 :             :     integer :: spacecom                      ! Communicator for MPI
      68                 :             :     integer :: paral_kgb                     ! paral_kgb formalism or not
      69                 :             :     integer :: comm_rows                     ! communicator for rows
      70                 :             :     integer :: comm_cols                     ! communicator for cols
      71                 :             :     integer :: me_g0
      72                 :             :     integer :: me_g0_fft
      73                 :             :     double precision :: tolerance            ! Tolerance on the residu to stop the minimization
      74                 :             :     integer :: prtvol
      75                 :             :     type(xg_nonlop_t) :: xg_nonlop ! contains data for nonlocal operations
      76                 :             :     type(xgBlock_t) :: AllX0 ! Block of initial and final solution.
      77                 :             :     type(xgBlock_t) :: AllcprjX0 ! Block of initial and final solution.
      78                 :             :     type(xgBlock_t) :: X0
      79                 :             :     type(xgBlock_t) :: cprjX0
      80                 :             :                                              ! Dim is (cplx*spacedim,neigenpair)
      81                 :             :     !double precision, allocatable :: eig(:)  ! Actual eigen values
      82                 :             : 
      83                 :             :     ! Some denomination here
      84                 :             :     ! X, W, P are the shifts where their block vectors starts.
      85                 :             :     ! X is the current block we are solving
      86                 :             :     ! W is the residu of the pencil A-lambda*B ie W=A*X-lambdaB*X
      87                 :             :     ! P correspond to X_{iline} - X_{iline-1}
      88                 :             :     ! if prefixed by A (AX, AW, AP) it means the result of A*X (A*W, A*P ! respectively)
      89                 :             :     ! Idem for B (BX, BW, BP) which is the result of B*X (B*W, B*P)
      90                 :             :     ! An extend to this is AXWP which is the vector [AX,AW,AP]
      91                 :             :     ! and BXWP which is [BX,BW,BP] columnwise
      92                 :             :     ! Now we only allocate the triple XWP matrix and each individual X, W and P
      93                 :             :     ! Example : XWP=[x1,x2,x3,w1,w2,w3,p1,p2,p3] X points to the indice of x1-1, W points to w1-1 and
      94                 :             :     ! P to p1-1
      95                 :             :     type(xg_t) :: XWP
      96                 :             :     type(xg_t) :: AXWP
      97                 :             :     type(xg_t) :: cprjXWP
      98                 :             : 
      99                 :             :     type(xg_t) :: cprj_work
     100                 :             :     type(xg_t) :: cprj_work2
     101                 :             : 
     102                 :             :     type(xgBlock_t) :: XColsRows
     103                 :             :     type(xgBlock_t) :: AXColsRows
     104                 :             : 
     105                 :             :     type(xgTransposer_t) :: xgTransposerX
     106                 :             :     type(xgTransposer_t) :: xgTransposerAX
     107                 :             : 
     108                 :             :     type(xgBlock_t) :: WColsRows
     109                 :             :     type(xgBlock_t) :: AWColsRows
     110                 :             : 
     111                 :             :     type(xgTransposer_t) :: xgTransposerW
     112                 :             :     type(xgTransposer_t) :: xgTransposerAW
     113                 :             : 
     114                 :             :     type(xgBlock_t) :: X ! Shift to apply to start reading the X values
     115                 :             :     type(xgBlock_t) :: W ! Shift to apply to start reading the W values
     116                 :             :     type(xgBlock_t) :: P ! Shift to apply to start reading the P values
     117                 :             :     type(xgBlock_t) :: XW ! Shift to apply to start reading the P values
     118                 :             :     type(xgBlock_t) :: WP ! Shift to apply to start reading the P values
     119                 :             : 
     120                 :             :     type(xgBlock_t) :: AX ! Shift to apply to start reading the X values
     121                 :             :     type(xgBlock_t) :: AW ! Shift to apply to start reading the W values
     122                 :             :     type(xgBlock_t) :: AP ! Shift to apply to start reading the P values
     123                 :             :     type(xgBlock_t) :: AXW ! Shift to apply to start reading the P values
     124                 :             :     type(xgBlock_t) :: AWP ! Shift to apply to start reading the P values
     125                 :             : 
     126                 :             :     type(xgBlock_t) :: cprjX ! Shift to apply to start reading the X values
     127                 :             :     type(xgBlock_t) :: cprjW ! Shift to apply to start reading the W values
     128                 :             :     type(xgBlock_t) :: cprjP ! Shift to apply to start reading the P values
     129                 :             :     type(xgBlock_t) :: cprjXW ! Shift to apply to start reading the P values
     130                 :             :     type(xgBlock_t) :: cprjWP ! Shift to apply to start reading the P values
     131                 :             : 
     132                 :             :     type(xg_t) :: AllAX0
     133                 :             : 
     134                 :             :     type(xgBlock_t) :: AllX0ColsRows
     135                 :             :     type(xgBlock_t) :: AllAX0ColsRows
     136                 :             : 
     137                 :             :     type(xgTransposer_t) :: xgTransposerAllX0
     138                 :             :     type(xgTransposer_t) :: xgTransposerAllAX0
     139                 :             : 
     140                 :             :   end type lobpcg_t
     141                 :             : 
     142                 :             :   public :: lobpcg_init
     143                 :             :   public :: lobpcg_memInfo
     144                 :             :   public :: lobpcg_run_cprj
     145                 :             :   public :: lobpcg_free
     146                 :             : 
     147                 :             :   contains
     148                 :             : 
     149                 :             : 
     150                 :        4036 :   subroutine lobpcg_init(lobpcg, bandpp, neigenpairs, spacedim, cprjdim, blockdim, tolerance, nline, &
     151                 :             : &      space, space_cprj, spacecom, paral_kgb, xg_nonlop, comm_rows, comm_cols, me_g0, me_g0_fft)
     152                 :             : 
     153                 :             :     type(lobpcg_t)   , intent(inout) :: lobpcg
     154                 :             :     type(xg_nonlop_t), intent(in   ) :: xg_nonlop
     155                 :             :     integer          , intent(in   ) :: neigenpairs
     156                 :             :     integer          , intent(in   ) :: spacedim
     157                 :             :     integer          , intent(in   ) :: cprjdim
     158                 :             :     integer          , intent(in   ) :: blockdim
     159                 :             :     integer          , intent(in   ) :: bandpp
     160                 :             :     double precision , intent(in   ) :: tolerance
     161                 :             :     integer          , intent(in   ) :: nline
     162                 :             :     integer          , intent(in   ) :: comm_rows,comm_cols
     163                 :             :     integer          , intent(in   ) :: space
     164                 :             :     integer          , intent(in   ) :: space_cprj
     165                 :             :     integer          , intent(in   ) :: spacecom
     166                 :             :     integer          , intent(in   ) :: paral_kgb
     167                 :             :     integer          , intent(in   ) :: me_g0
     168                 :             :     integer          , intent(in   ) :: me_g0_fft
     169                 :             :     double precision :: tsec(2)
     170                 :             : 
     171                 :        4036 :     call timab(tim_init,1,tsec)
     172                 :        4036 :     lobpcg%neigenpairs   = neigenpairs
     173                 :        4036 :     lobpcg%spacedim      = spacedim
     174                 :        4036 :     lobpcg%space         = space
     175                 :        4036 :     lobpcg%space_cprj    = space_cprj
     176                 :        4036 :     lobpcg%cprjdim       = cprjdim
     177                 :        4036 :     lobpcg%nblock        = neigenpairs / blockdim
     178                 :        4036 :     lobpcg%blockdim      = blockdim
     179                 :        4036 :     lobpcg%blockdim_cprj = bandpp*xg_nonlop%nspinor
     180         [ -  + ]:        4036 :     if (tolerance > 0.0) then
     181                 :           0 :       lobpcg%tolerance   = tolerance
     182                 :             :     else
     183                 :        4036 :       lobpcg%tolerance   = 1e-20
     184                 :             :     end if
     185                 :        4036 :     lobpcg%nline         = nline
     186                 :        4036 :     lobpcg%spacecom      = spacecom
     187                 :        4036 :     lobpcg%paral_kgb     = paral_kgb
     188                 :        4036 :     lobpcg%comm_rows     = comm_rows
     189                 :        4036 :     lobpcg%comm_cols     = comm_cols
     190   [ +  -  +  -  :        4036 :     lobpcg%xg_nonlop     = xg_nonlop
          +  -  +  -  +  
          -  +  -  -  +  
          -  +  -  +  -  
                      + ]
     191                 :        4036 :     lobpcg%me_g0         = me_g0
     192                 :        4036 :     lobpcg%me_g0_fft     = me_g0_fft
     193                 :             : 
     194                 :        4036 :     call lobpcg_allocateAll(lobpcg)
     195                 :        4036 :     call timab(tim_init,2,tsec)
     196                 :             : 
     197                 :        4036 :   end subroutine lobpcg_init
     198                 :             : 
     199                 :             : 
     200                 :        4036 :   subroutine lobpcg_allocateAll(lobpcg)
     201                 :             : 
     202                 :             :     type(lobpcg_t)  , intent(inout) :: lobpcg
     203                 :             :     integer :: spacedim
     204                 :             :     integer :: cprjdim
     205                 :             :     integer :: blockdim
     206                 :             :     integer :: blockdim_cprj
     207                 :             : 
     208                 :        4036 :     spacedim = lobpcg%spacedim
     209                 :        4036 :     blockdim = lobpcg%blockdim
     210                 :             : 
     211                 :        4036 :     cprjdim       = lobpcg%cprjdim
     212                 :        4036 :     blockdim_cprj = lobpcg%blockdim_cprj
     213                 :             : 
     214                 :        4036 :     call lobpcg_free(lobpcg) ! Make sure everything is not allocated and
     215                 :             :     ! pointer point to null()
     216                 :             : 
     217                 :        4036 :     call xg_init(lobpcg%XWP,lobpcg%space,spacedim,3*blockdim,lobpcg%spacecom,me_g0=lobpcg%me_g0)
     218                 :        4036 :     call xg_setBlock(lobpcg%XWP,lobpcg%X,spacedim,blockdim)
     219                 :        4036 :     call xg_setBlock(lobpcg%XWP,lobpcg%W,spacedim,blockdim,fcol=blockdim+1)
     220                 :        4036 :     call xg_setBlock(lobpcg%XWP,lobpcg%P,spacedim,blockdim,fcol=2*blockdim+1)
     221                 :        4036 :     call xg_setBlock(lobpcg%XWP,lobpcg%XW,spacedim,2*blockdim)
     222                 :        4036 :     call xg_setBlock(lobpcg%XWP,lobpcg%WP,spacedim,2*blockdim,fcol=blockdim+1)
     223                 :             : 
     224                 :        4036 :     call xg_init(lobpcg%AXWP,lobpcg%space,spacedim,3*blockdim,lobpcg%spacecom,me_g0=lobpcg%me_g0)
     225                 :        4036 :     call xg_setBlock(lobpcg%AXWP,lobpcg%AX,spacedim,blockdim)
     226                 :        4036 :     call xg_setBlock(lobpcg%AXWP,lobpcg%AW,spacedim,blockdim,fcol=blockdim+1)
     227                 :        4036 :     call xg_setBlock(lobpcg%AXWP,lobpcg%AP,spacedim,blockdim,fcol=2*blockdim+1)
     228                 :        4036 :     call xg_setBlock(lobpcg%AXWP,lobpcg%AXW,spacedim,2*blockdim)
     229                 :        4036 :     call xg_setBlock(lobpcg%AXWP,lobpcg%AWP,spacedim,2*blockdim,fcol=blockdim+1)
     230                 :             : 
     231                 :        4036 :     call xg_init(lobpcg%cprjXWP,lobpcg%space_cprj,cprjdim,3*blockdim_cprj,lobpcg%spacecom)
     232                 :        4036 :     call xg_setBlock(lobpcg%cprjXWP,lobpcg%cprjX, cprjdim,  blockdim_cprj)
     233                 :        4036 :     call xg_setBlock(lobpcg%cprjXWP,lobpcg%cprjW, cprjdim,  blockdim_cprj,fcol=   blockdim_cprj+1)
     234                 :        4036 :     call xg_setBlock(lobpcg%cprjXWP,lobpcg%cprjP, cprjdim,  blockdim_cprj,fcol= 2*blockdim_cprj+1)
     235                 :        4036 :     call xg_setBlock(lobpcg%cprjXWP,lobpcg%cprjXW,cprjdim,2*blockdim_cprj)
     236                 :        4036 :     call xg_setBlock(lobpcg%cprjXWP,lobpcg%cprjWP,cprjdim,2*blockdim_cprj,fcol=   blockdim_cprj+1)
     237                 :             : 
     238                 :        4036 :     call xg_init(lobpcg%cprj_work ,lobpcg%space_cprj,cprjdim,blockdim_cprj,lobpcg%spacecom)
     239                 :        4036 :     call xg_init(lobpcg%cprj_work2,lobpcg%space_cprj,cprjdim,blockdim_cprj,lobpcg%spacecom)
     240                 :             : 
     241         [ +  + ]:        4036 :     if ( lobpcg%nblock /= 1 ) then
     242                 :        4004 :       call xg_init(lobpcg%AllAX0,lobpcg%space,spacedim,lobpcg%neigenpairs,lobpcg%spacecom,me_g0=lobpcg%me_g0)
     243                 :             :     else
     244                 :          32 :       lobpcg%AllAX0%self = lobpcg%AX
     245                 :             :     end if
     246                 :             : 
     247                 :        4036 :   end subroutine lobpcg_allocateAll
     248                 :             : 
     249                 :             : 
     250         [ #  # ]:           0 :   function lobpcg_memInfo(neigenpairs, spacedim, blockdim, space) result(arraymem)
     251                 :             : 
     252                 :             :     integer         , intent(in   ) :: neigenpairs
     253                 :             :     integer         , intent(in   ) :: spacedim
     254                 :             :     integer         , intent(in   ) :: blockdim
     255                 :             :     integer         , intent(in   ) :: space
     256                 :             :     double precision :: memXWP
     257                 :             :     double precision :: memAXWP
     258                 :             :     double precision :: memBXWP
     259                 :             :     double precision :: memAllBX0
     260                 :             :     double precision :: memAllAX0
     261                 :             :     double precision :: memeigenvalues3N
     262                 :             :     double precision :: membufferOrtho
     263                 :             :     double precision :: membufferBOrtho
     264                 :             :     double precision :: memsubA
     265                 :             :     double precision :: memsubB
     266                 :             :     double precision :: memsubBtmp
     267                 :             :     double precision :: memvec
     268                 :             :     double precision :: memRR
     269                 :             :     double precision :: maxmemTmp
     270                 :             :     double precision :: cplx
     271                 :             :     integer :: nblock
     272                 :             :     double precision :: arraymem(2)
     273                 :             : 
     274         [ #  # ]:           0 :     cplx = 1 ; if ( space == SPACE_C ) cplx = 2
     275                 :           0 :     nblock = neigenpairs/blockdim
     276                 :             : 
     277                 :             :     ! Permanent in lobpcg
     278                 :           0 :     memXWP  = cplx* kind(1.d0) * spacedim * 3*blockdim
     279                 :           0 :     memAXWP = cplx* kind(1.d0) * spacedim * 3*blockdim
     280                 :           0 :     memBXWP = cplx* kind(1.d0) * spacedim * 3*blockdim
     281         [ #  # ]:           0 :     if ( nblock > 1 ) then
     282                 :           0 :       memAllAX0 = cplx * kind(1.d0) * spacedim * 3*blockdim
     283                 :           0 :       memAllBX0 = cplx * kind(1.d0) * spacedim * 3*blockdim
     284                 :           0 :       membufferOrtho = cplx * kind(1.d0) * blockdim * (nblock-1) * blockdim
     285                 :             :     else
     286                 :             :       memAllAX0 = 0
     287                 :             :       memAllBX0 = 0
     288                 :             :       membufferOrtho = 0
     289                 :             :     endif
     290                 :           0 :     memeigenvalues3N = kind(1.d0) * 3*blockdim
     291                 :             : 
     292                 :             :     ! Temporary arrays
     293                 :           0 :     membufferBOrtho = cplx * kind(1.d0) * 2*blockdim * 2*blockdim ! For the moment being, only Bortho with X or WP at the same time
     294                 :           0 :     memsubA = cplx * kind(1.d0) * 3*blockdim * 3*blockdim
     295                 :           0 :     memsubB = cplx * kind(1.d0) * 3*blockdim * 3*blockdim
     296                 :           0 :     memsubBtmp = cplx * kind(1.d0) * spacedim * blockdim
     297                 :           0 :     memvec = cplx * kind(1.d0) * 3*blockdim * blockdim
     298                 :           0 :     memRR = max(memsubA+memsubB+memvec,memsubBtmp+memvec)
     299                 :             : 
     300                 :           0 :     maxmemTmp = max( membufferBOrtho,memRR,membufferOrtho )
     301                 :             : 
     302                 :           0 :     arraymem(1) = memXWP+memAXWP+memBXWP+memAllAX0+memAllBX0+memeigenvalues3N
     303                 :           0 :     arraymem(2) = maxmemTmp
     304                 :             : 
     305                 :           0 :   end function lobpcg_memInfo
     306                 :             : 
     307                 :             : 
     308                 :       12108 :   subroutine lobpcg_run_cprj(lobpcg, X0, cprjX0, getAX, kin, pcond, eigen, occ, residu, enl, prtvol, nspinor, &
     309                 :             :       isppol, ikpt, inonsc, istep, nbdbuf)
     310                 :             : 
     311                 :             :     type(lobpcg_t) , intent(inout) :: lobpcg
     312                 :             :     type(xgBlock_t), intent(inout) :: X0      ! Full initial vectors
     313                 :             :     type(xgBlock_t), intent(inout) :: cprjX0  ! Full initial cprj
     314                 :             :     type(xgBlock_t), intent(inout) :: eigen   ! Full initial eigen values
     315                 :             :     type(xgBlock_t), intent(inout) :: occ
     316                 :             :     type(xgBlock_t), intent(inout) :: residu
     317                 :             :     type(xgBlock_t), intent(inout) :: enl
     318                 :             :     type(xgBlock_t), intent(in   ) :: kin
     319                 :             :     type(xgBlock_t), intent(in   ) :: pcond
     320                 :             :     integer        , intent(in   ) :: prtvol
     321                 :             :     integer        , intent(in   ) :: nspinor
     322                 :             :     integer        , intent(in   ) :: isppol,ikpt,inonsc,istep,nbdbuf
     323                 :             : 
     324                 :             :     type(xg_t) :: eigenvalues3N   ! eigen values for Rayleight-Ritz
     325                 :             :     type(xg_t) :: residu_eff
     326                 :             :     type(xgBlock_t) :: eigenvaluesN   ! eigen values for Rayleight-Ritz
     327                 :             :     type(xgBlock_t) :: eigenvalues2N   ! eigen values for Rayleight-Ritz
     328                 :             :     logical :: skip,compute_residu
     329                 :             :     integer :: blockdim, blockdim3, blockdim2, blockdim_cprj
     330                 :             :     integer :: spacedim
     331                 :             :     integer :: iblock, nblock
     332                 :             :     integer :: iline, nline
     333                 :             :     integer :: rows_tmp, cols_tmp, nband_eff, iband_min, iband_max
     334                 :             :     integer,parameter :: gpu_option=ABI_GPU_DISABLED
     335                 :             :     type(xgBlock_t) :: eigenBlock   !
     336                 :             :     type(xgBlock_t) :: residuBlock,occBlock
     337                 :             :     type(xg_t):: cprj_work_all
     338                 :             :     double precision :: maxResidu, minResidu, dummy
     339                 :             :     double precision :: dlamch,tolerance
     340                 :             :     integer :: ierr = 0
     341                 :             :     integer :: nrestart
     342                 :             :     double precision :: tsec(2)
     343                 :             :     character(len=500) :: msg
     344                 :             : 
     345                 :             :     interface
     346                 :             :       subroutine getAX(X,AX)
     347                 :             :         use m_xg, only : xgBlock_t
     348                 :             :         type(xgBlock_t), intent(inout) :: X
     349                 :             :         type(xgBlock_t), intent(inout) :: AX
     350                 :             :       end subroutine getAX
     351                 :             :     end interface
     352                 :             : 
     353                 :        4036 :     lobpcg%prtvol = prtvol
     354                 :             : 
     355                 :        8072 :     tolerance=2*dlamch('E')
     356                 :             : 
     357                 :        4036 :     blockdim = lobpcg%blockdim
     358                 :        4036 :     blockdim2 = 2*blockdim
     359                 :        4036 :     blockdim3 = 3*blockdim
     360                 :        4036 :     blockdim_cprj = lobpcg%blockdim_cprj
     361                 :        4036 :     spacedim = lobpcg%spacedim
     362                 :             : 
     363                 :        4036 :     nblock = lobpcg%nblock
     364                 :        4036 :     nline = lobpcg%nline
     365                 :             : 
     366         [ +  - ]:        4036 :     if (nbdbuf>0) then
     367                 :        4036 :        nband_eff = lobpcg%neigenpairs - nbdbuf
     368                 :             :     else
     369                 :           0 :        nband_eff = lobpcg%neigenpairs
     370                 :             :     end if
     371                 :             : 
     372                 :        4036 :     call xgBlock_getSize(eigen,rows_tmp, cols_tmp)
     373   [ -  +  -  - ]:        4036 :     if ( rows_tmp /= lobpcg%neigenpairs .and. cols_tmp /= 1 ) then
     374                 :           0 :       ABI_ERROR("Error eigen size")
     375                 :             :     endif
     376                 :        4036 :     call xgBlock_getSize(X0,rows_tmp, cols_tmp)
     377         [ -  + ]:        4036 :     if ( rows_tmp /= lobpcg%spacedim ) then
     378                 :           0 :       ABI_ERROR("Error X0 spacedim")
     379                 :             :     endif
     380         [ -  + ]:        4036 :     if ( cols_tmp /= lobpcg%neigenpairs ) then
     381                 :           0 :       ABI_ERROR("Error X0 npairs")
     382                 :             :     endif
     383                 :             : 
     384   [ +  +  +  +  :        4036 :     if (isppol==1.and.ikpt==1.and.inonsc==1.and.istep==1) then
             +  +  +  + ]
     385                 :          42 :       write(msg,'(a,es16.6)') ' lobpcg%tolerance(tolwfr_diago)=',lobpcg%tolerance
     386                 :          42 :       call wrtout(std_out,msg,'COLL')
     387                 :             :     end if
     388                 :             : 
     389                 :        4036 :     call xg_init(eigenvalues3N,SPACE_R,blockdim3,1)
     390                 :        4036 :     call xg_setBlock(eigenvalues3N,eigenvaluesN,blockdim,1)
     391                 :        4036 :     call xg_setBlock(eigenvalues3N,eigenvalues2N,blockdim2,1)
     392                 :             : 
     393                 :        4036 :     call xgBlock_reshape(eigen,blockdim,nblock)
     394                 :        4036 :     call xgBlock_reshape(residu,blockdim,nblock)
     395                 :        4036 :     call xgBlock_reshape(occ,blockdim,nblock)
     396                 :             : 
     397                 :        4036 :     lobpcg%AllX0     = X0
     398                 :        4036 :     lobpcg%AllcprjX0 = cprjX0
     399                 :             : 
     400                 :        4036 :     call xg_init(residu_eff,SPACE_R,blockdim,1,gpu_option=ABI_GPU_DISABLED)
     401                 :             : 
     402         [ +  + ]:        4036 :     if ( lobpcg%paral_kgb == 1 ) then
     403                 :        2684 :       call timab(tim_transpose,1,tsec)
     404                 :             :       call xgTransposer_constructor(lobpcg%xgTransposerX,lobpcg%X,lobpcg%XColsRows,nspinor,&
     405                 :        2684 :         STATE_LINALG,TRANS_ALL2ALL,lobpcg%comm_rows,lobpcg%comm_cols,0,0,lobpcg%me_g0_fft)
     406                 :             :       call xgTransposer_copyConstructor(lobpcg%xgTransposerAX,lobpcg%xgTransposerX,&
     407                 :        2684 :         lobpcg%AX,lobpcg%AXColsRows,STATE_LINALG)
     408                 :             :       call xgTransposer_copyConstructor(lobpcg%xgTransposerW,lobpcg%xgTransposerX,&
     409                 :        2684 :         lobpcg%W,lobpcg%WColsRows,STATE_LINALG)
     410                 :             :       call xgTransposer_copyConstructor(lobpcg%xgTransposerAW,lobpcg%xgTransposerX,&
     411                 :        2684 :         lobpcg%AW,lobpcg%AWColsRows,STATE_LINALG)
     412                 :        2684 :       call timab(tim_transpose,2,tsec)
     413                 :             :     else
     414                 :        1352 :       call xgBlock_setBlock(lobpcg%X, lobpcg%XColsRows, spacedim, blockdim)
     415                 :        1352 :       call xgBlock_setBlock(lobpcg%AX, lobpcg%AXColsRows, spacedim, blockdim)
     416                 :        1352 :       call xgBlock_setBlock(lobpcg%W, lobpcg%WColsRows, spacedim, blockdim)
     417                 :        1352 :       call xgBlock_setBlock(lobpcg%AW, lobpcg%AWColsRows, spacedim, blockdim)
     418                 :             :     end if
     419                 :             : 
     420                 :             :     !! Start big loop over blocks
     421         [ +  + ]:       20628 :     do iblock = 1, nblock
     422                 :       16592 :       nrestart = 0
     423                 :             : 
     424                 :       16592 :       call lobpcg_getX0(lobpcg,iblock)
     425                 :       16592 :       call xgBlock_setBlock(residu,residuBlock,blockdim,1,fcol=iblock)
     426                 :       16592 :       call xgBlock_setBlock(occ,   occBlock,   blockdim,1,fcol=iblock)
     427                 :             : 
     428                 :       16592 :       call timab(tim_cprj,1,tsec)
     429                 :       16592 :       call xg_nonlop_getcprj(lobpcg%xg_nonlop,lobpcg%X,lobpcg%cprjX,lobpcg%cprj_work%self)
     430                 :       16592 :       call timab(tim_cprj,2,tsec)
     431                 :             : 
     432         [ +  + ]:       16592 :       if ( iblock > 1 ) then
     433                 :       12556 :         call lobpcg_setPreviousX0(lobpcg,iblock)
     434                 :             :         ! Orthogonalize current iblock X block With Respect To previous Blocks in B-basis
     435                 :       12556 :         call lobpcg_orthoXwrtBlocks(lobpcg,lobpcg%X,lobpcg%cprjX,iblock,lobpcg%cprj_work%self)
     436                 :             :       end if
     437                 :             : 
     438         [ +  + ]:       16592 :       if (lobpcg%paral_kgb == 1) then
     439                 :       11184 :         call timab(tim_transpose,1,tsec)
     440                 :       11184 :         call xgTransposer_transpose(lobpcg%xgTransposerX,STATE_COLSROWS)
     441                 :       11184 :         lobpcg%xgTransposerAX%state=STATE_COLSROWS
     442                 :       11184 :         call timab(tim_transpose,2,tsec)
     443                 :             :       end if
     444                 :             : 
     445                 :             :       ! Initialize some quantitites (AX)
     446                 :       16592 :       call timab(tim_ax_v,1,tsec)
     447                 :       16592 :       call getAX(lobpcg%XColsRows,lobpcg%AXColsRows)
     448                 :       16592 :       call xgBlock_zero_im_g0(lobpcg%AXColsRows)
     449                 :       16592 :       call timab(tim_ax_v,2,tsec)
     450         [ +  + ]:       16592 :       if (lobpcg%paral_kgb == 1) then
     451                 :       11184 :         call timab(tim_transpose,1,tsec)
     452                 :       11184 :         lobpcg%xgTransposerX%state=STATE_LINALG
     453                 :       11184 :         call xgTransposer_transpose(lobpcg%xgTransposerAX,STATE_LINALG)
     454                 :       11184 :         call timab(tim_transpose,2,tsec)
     455                 :             :       end if
     456                 :             : 
     457                 :       16592 :       call timab(tim_ax_k,1,tsec)
     458                 :       16592 :       call xgBlock_add_diag(lobpcg%X,kin,nspinor,lobpcg%AX)
     459                 :       16592 :       call timab(tim_ax_k,2,tsec)
     460                 :             : 
     461                 :             :       ! B-orthonormalize X, BX and AX
     462                 :       16592 :       call xg_Borthonormalize_cprj(lobpcg%xg_nonlop,lobpcg%X,lobpcg%cprjX,ierr,tim_Bortho_X,gpu_option,AX=lobpcg%AX)
     463                 :             : 
     464                 :             :       ! Do first RR on X to get the first eigen values
     465                 :             :       call xg_RayleighRitz_cprj(lobpcg%xg_nonlop,lobpcg%X,lobpcg%cprjX,lobpcg%AX,eigenvaluesN,ierr,&
     466                 :       16592 :         & lobpcg%prtvol,tim_RR_X,gpu_option,add_Anl=.True.)
     467                 :             : 
     468                 :       16592 :       compute_residu = .true.
     469                 :             : 
     470         [ +  + ]:       75096 :       do iline = 1, nline
     471                 :             : 
     472         [ -  + ]:       67717 :         if ( ierr /= 0 ) then
     473                 :             :           !ABI_COMMENT("Consider using more bands and nbdbuf if necessary.")
     474                 :           0 :           ierr = 0
     475                 :             :         end if
     476                 :             : 
     477                 :             :         ! Compute AX-Lambda*BX
     478                 :       67717 :         call timab(tim_copy,1,tsec)
     479                 :       67717 :         call xgBlock_copy(lobpcg%AX,lobpcg%W)
     480                 :       67717 :         call timab(tim_copy,2,tsec)
     481                 :             :         ! Add the non-local part: (A_nl - Lambda*B)X
     482                 :       67717 :         call timab(tim_ax_nl,1,tsec)
     483         [ +  + ]:       67717 :         if (lobpcg%xg_nonlop%paw) then
     484                 :             :           call xg_nonlop_getHmeSX(lobpcg%xg_nonlop,lobpcg%X,lobpcg%cprjX,lobpcg%W,eigenvaluesN,&
     485                 :       55920 :             lobpcg%cprj_work%self,lobpcg%cprj_work2%self)
     486                 :             :         else
     487                 :             :           call xg_nonlop_getHX(lobpcg%xg_nonlop,lobpcg%W,lobpcg%cprjX,&
     488                 :       11797 :             lobpcg%cprj_work%self,lobpcg%cprj_work2%self)
     489                 :       11797 :           call xgBlock_yxmax(lobpcg%W,eigenvaluesN,lobpcg%X)
     490                 :             :         end if
     491                 :       67717 :         call timab(tim_ax_nl,2,tsec)
     492                 :             : 
     493                 :             :         ! Compute residu norm here !
     494                 :       67717 :         call timab(tim_maxres,1,tsec)
     495                 :       67717 :         call xgBlock_colwiseNorm2(lobpcg%W,residuBlock)
     496                 :       67717 :         call timab(tim_maxres,2,tsec)
     497                 :             : 
     498                 :             :         ! Apply preconditioner
     499                 :       67717 :         call timab(tim_pcond,1,tsec)
     500                 :       67717 :         call xgBlock_apply_diag(lobpcg%W,pcond,nspinor)
     501                 :       67717 :         call timab(tim_pcond,2,tsec)
     502                 :             : 
     503                 :       67717 :         call timab(tim_nbdbuf,1,tsec)
     504         [ +  - ]:       67717 :         if (nbdbuf>=0) then
     505                 :             :           ! There is a transfer from GPU to CPU in this copy
     506                 :       67717 :           call xgBlock_copy(residuBlock,residu_eff%self)
     507                 :       67717 :           iband_min = 1 + blockdim*(iblock-1)
     508                 :       67717 :           iband_max = blockdim*iblock
     509         [ +  + ]:       67717 :           if (iband_max<=nband_eff) then ! all bands of this block are below nband_eff
     510                 :       57269 :             call xgBlock_minmax(residu_eff%self,minResidu,maxResidu)
     511         [ +  + ]:       10448 :           else if (iband_min<=nband_eff) then ! some bands of this block are below nband_eff
     512                 :        3120 :             call xgBlock_minmax(residu_eff%self,minResidu,maxResidu,row_bound=(nband_eff-iband_min+1))
     513                 :             :           else ! all bands of this block are above nband_eff
     514                 :        7328 :             minResidu = 0.0
     515                 :        7328 :             maxResidu = 0.0
     516                 :             :           end if
     517         [ #  # ]:           0 :         else if (nbdbuf==-101) then
     518                 :           0 :           call xgBlock_minmax(residuBlock,minResidu,dummy) ! Get minimum of true residuals
     519                 :             :           ! Compute effective residuals : res_eff = res * occ
     520                 :           0 :           call xgBlock_apply_diag(residuBlock,occBlock,1,Y=residu_eff%self)
     521                 :           0 :           call xgBlock_minmax(residu_eff%self,dummy,maxResidu) ! Get maximum of effective residuals
     522                 :             :         else
     523                 :           0 :           ABI_ERROR('Bad value of nbdbuf')
     524                 :             :         end if
     525                 :       67717 :         call timab(tim_nbdbuf,2,tsec)
     526         [ +  + ]:       67717 :         if ( maxResidu < lobpcg%tolerance ) then
     527                 :             :           compute_residu = .false.
     528                 :             :           exit
     529                 :             :         end if
     530                 :             : 
     531                 :       58504 :         call timab(tim_cprj,1,tsec)
     532                 :       58504 :         call xg_nonlop_getcprj(lobpcg%xg_nonlop,lobpcg%W,lobpcg%cprjW,lobpcg%cprj_work%self)
     533                 :       58504 :         call timab(tim_cprj,2,tsec)
     534                 :             : 
     535                 :             :         ! Orthonormalize with respect to previous blocks
     536         [ +  + ]:       58504 :         if ( iblock > 1 ) then
     537                 :       32398 :           call lobpcg_orthoXwrtBlocks(lobpcg,lobpcg%W,lobpcg%cprjW,iblock,lobpcg%cprj_work%self)
     538                 :             :         end if
     539                 :             : 
     540         [ +  + ]:       58504 :         if (lobpcg%paral_kgb == 1) then
     541                 :       37406 :           call timab(tim_transpose,1,tsec)
     542                 :       37406 :           call xgTransposer_transpose(lobpcg%xgTransposerW,STATE_COLSROWS)
     543                 :       37406 :           lobpcg%xgTransposerAW%state=STATE_COLSROWS
     544                 :       37406 :           call timab(tim_transpose,2,tsec)
     545                 :             :         end if
     546                 :             :         ! Apply A and B on W
     547                 :       58504 :         call timab(tim_ax_v,1,tsec)
     548                 :       58504 :         call getAX(lobpcg%WColsRows,lobpcg%AWColsRows)
     549                 :       58504 :         call xgBlock_zero_im_g0(lobpcg%AWColsRows)
     550                 :       58504 :         call timab(tim_ax_v,2,tsec)
     551         [ +  + ]:       58504 :         if (lobpcg%paral_kgb == 1) then
     552                 :       37406 :           call timab(tim_transpose,1,tsec)
     553                 :       37406 :           lobpcg%xgTransposerW%state=STATE_LINALG
     554                 :       37406 :           call xgTransposer_transpose(lobpcg%xgTransposerAW,STATE_LINALG)
     555                 :       37406 :           call timab(tim_transpose,2,tsec)
     556                 :             :         end if
     557                 :             : 
     558                 :       58504 :         call timab(tim_ax_k,1,tsec)
     559                 :       58504 :         call xgBlock_add_diag(lobpcg%W,kin,nspinor,lobpcg%AW)
     560                 :       58504 :         call timab(tim_ax_k,2,tsec)
     561                 :             : 
     562                 :             :         ! DO RR in the correct subspace
     563                 :             :         ! if residu starts to be too small, there is an accumulation error in
     564                 :             :         ! P with values such as 1e-29 that make the eigenvectors diverge
     565   [ +  +  -  + ]:       65883 :         if ( iline == 1 .or. minResidu < 1e-27) then
     566                 :             :           ! Do RR on XW to get the eigen vectors
     567                 :             :           call xg_Borthonormalize_cprj(lobpcg%xg_nonlop,lobpcg%XW,lobpcg%cprjXW,&
     568                 :        8938 :             & ierr,tim_Bortho_XW,gpu_option,AX=lobpcg%AXW,blockdim_cprj=blockdim_cprj)
     569                 :        8938 :           call xgBlock_zero(lobpcg%P)
     570                 :        8938 :           call xgBlock_zero(lobpcg%AP)
     571                 :        8938 :           call xgBlock_zero(lobpcg%cprjP)
     572         [ -  + ]:        8938 :           if ( ierr /= 0 ) then
     573                 :           0 :             ABI_COMMENT("B-orthonormalization (XW) did not work.")
     574                 :             :           end if
     575                 :             :           call xg_RayleighRitz_cprj(lobpcg%xg_nonlop,lobpcg%X,lobpcg%cprjX,lobpcg%AX,eigenvaluesN,ierr,&
     576                 :             :            & lobpcg%prtvol,tim_RR_XW,gpu_option,tolerance=tolerance,&
     577                 :             :            & XW=lobpcg%XW,W=lobpcg%W,cprjXW=lobpcg%cprjXW,cprjW=lobpcg%cprjW,AW=lobpcg%AW,&
     578                 :             :            & P=lobpcg%P,cprjP=lobpcg%cprjP,AP=lobpcg%AP,WP=lobpcg%WP,cprjWP=lobpcg%cprjWP,&
     579                 :        8938 :            & AWP=lobpcg%AWP,blockdim_cprj=blockdim_cprj,add_Anl=.True.)
     580         [ -  + ]:        8938 :           if ( ierr /= 0 ) then
     581                 :           0 :             ABI_WARNING("RayleighRitz (XW) did not work, but continue anyway.")
     582                 :             :             exit
     583                 :             :           end if
     584                 :             :         else
     585                 :             :           ! B-orthonormalize P, BP
     586                 :             :           call xg_Borthonormalize_cprj(lobpcg%xg_nonlop,lobpcg%XWP%self,lobpcg%cprjXWP%self,&
     587                 :       49566 :             & ierr,tim_Bortho_XWP,gpu_option,AX=lobpcg%AXWP%self,blockdim_cprj=blockdim_cprj)
     588                 :             :           ! Do RR on XWP to get the eigen vectors
     589         [ +  - ]:       49566 :           if ( ierr == 0 ) then
     590                 :             :             call xg_RayleighRitz_cprj(lobpcg%xg_nonlop,lobpcg%X,lobpcg%cprjX,lobpcg%AX,eigenvaluesN,ierr,&
     591                 :             :              & lobpcg%prtvol,tim_RR_XWP,gpu_option,tolerance=tolerance,&
     592                 :             :              & XW=lobpcg%XW,W=lobpcg%W,cprjXW=lobpcg%cprjXW,cprjW=lobpcg%cprjW,AW=lobpcg%AW,&
     593                 :             :              & P=lobpcg%P,cprjP=lobpcg%cprjP,AP=lobpcg%AP,WP=lobpcg%WP,cprjWP=lobpcg%cprjWP,&
     594                 :       49566 :              & AWP=lobpcg%AWP,XWP=lobpcg%XWP%self,cprjXWP=lobpcg%cprjXWP%self,blockdim_cprj=blockdim_cprj,add_Anl=.True.)
     595         [ -  + ]:       49566 :              if ( ierr /= 0 ) then
     596                 :           0 :                ABI_WARNING("RayleighRitz (XWP) did not work, but continue anyway.")
     597                 :             :                exit
     598                 :             :              end if
     599                 :             :           else
     600                 :           0 :             ABI_COMMENT("B-orthonormalization (XWP) did not work, try on XW.")
     601                 :             :             call xg_Borthonormalize_cprj(lobpcg%xg_nonlop,lobpcg%XW,lobpcg%cprjXW,&
     602                 :           0 :               & ierr,tim_Bortho_XW,gpu_option,AX=lobpcg%AXW,blockdim_cprj=blockdim_cprj)
     603         [ #  # ]:           0 :             if ( ierr /= 0 ) then
     604                 :           0 :               ABI_COMMENT("B-orthonormalization (XW) did not work.")
     605                 :             :             end if
     606                 :           0 :             call xgBlock_zero(lobpcg%P)
     607                 :           0 :             call xgBlock_zero(lobpcg%AP)
     608                 :           0 :             call xgBlock_zero(lobpcg%cprjP)
     609                 :           0 :             nrestart = nrestart + 1
     610                 :             :             call xg_RayleighRitz_cprj(lobpcg%xg_nonlop,lobpcg%X,lobpcg%cprjX,lobpcg%AX,eigenvaluesN,ierr,&
     611                 :             :              & lobpcg%prtvol,tim_RR_XW,gpu_option,tolerance=tolerance,&
     612                 :             :              & XW=lobpcg%XW,W=lobpcg%W,cprjXW=lobpcg%cprjXW,cprjW=lobpcg%cprjW,AW=lobpcg%AW,&
     613                 :             :              & P=lobpcg%P,cprjP=lobpcg%cprjP,AP=lobpcg%AP,WP=lobpcg%WP,cprjWP=lobpcg%cprjWP,&
     614                 :           0 :              & AWP=lobpcg%AWP,blockdim_cprj=blockdim_cprj,add_Anl=.True.)
     615         [ #  # ]:           0 :              if ( ierr /= 0 ) then
     616                 :           0 :                ABI_WARNING("RayleighRitz (XW) did not work, but continue anyway.")
     617                 :             :                exit
     618                 :             :              end if
     619                 :             :             end if
     620                 :             :         end if
     621                 :             : 
     622                 :             :       end do
     623                 :             : 
     624         [ +  + ]:       16592 :       if ( compute_residu ) then
     625                 :             :         ! Recompute AX-Lambda*BX for the last time
     626                 :        7379 :         call timab(tim_copy,1,tsec)
     627                 :        7379 :         call xgBlock_copy(lobpcg%AX,lobpcg%W)
     628                 :        7379 :         call timab(tim_copy,2,tsec)
     629                 :        7379 :         call timab(tim_ax_nl,1,tsec)
     630         [ +  + ]:        7379 :         if (lobpcg%xg_nonlop%paw) then
     631                 :             :           call xg_nonlop_getHmeSX(lobpcg%xg_nonlop,lobpcg%X,lobpcg%cprjX,lobpcg%W,eigenvaluesN,&
     632                 :        6305 :             lobpcg%cprj_work%self,lobpcg%cprj_work2%self)
     633                 :             :         else
     634                 :             :           call xg_nonlop_getHX(lobpcg%xg_nonlop,lobpcg%W,lobpcg%cprjX,&
     635                 :        1074 :             lobpcg%cprj_work%self,lobpcg%cprj_work2%self)
     636                 :        1074 :           call xgBlock_yxmax(lobpcg%W,eigenvaluesN,lobpcg%X)
     637                 :             :         end if
     638                 :        7379 :         call timab(tim_ax_nl,2,tsec)
     639                 :             :         ! Recompute residu norm here !
     640                 :        7379 :         call timab(tim_maxres,1,tsec)
     641                 :        7379 :         call xgBlock_colwiseNorm2(lobpcg%W,residuBlock)
     642                 :        7379 :         call timab(tim_maxres,2,tsec)
     643                 :             :         ! Apply preconditioner
     644                 :        7379 :         call timab(tim_pcond,1,tsec)
     645                 :        7379 :         call xgBlock_apply_diag(lobpcg%W,pcond,nspinor)
     646                 :        7379 :         call timab(tim_pcond,2,tsec)
     647                 :             : 
     648                 :        7379 :         call timab(tim_nbdbuf,1,tsec)
     649         [ +  - ]:        7379 :         if (nbdbuf>=0) then
     650                 :        7379 :           call xgBlock_copy(residuBlock,residu_eff%self)
     651                 :        7379 :           iband_min = 1 + blockdim*(iblock-1)
     652                 :        7379 :           iband_max = blockdim*iblock
     653         [ +  + ]:        7379 :           if (iband_max<=nband_eff) then ! all bands of this block are below nband_eff
     654                 :        6871 :             call xgBlock_minmax(residu_eff%self,minResidu,maxResidu)
     655         [ +  - ]:         508 :           else if (iband_min<=nband_eff) then ! some bands of this block are below nband_eff
     656                 :         508 :             call xgBlock_minmax(residu_eff%self,minResidu,maxResidu,row_bound=(nband_eff-iband_min+1))
     657                 :             :           else ! all bands of this block are above nband_eff
     658                 :           0 :             minResidu = 0.0
     659                 :           0 :             maxResidu = 0.0
     660                 :             :           end if
     661         [ #  # ]:           0 :         else if (nbdbuf==-101) then
     662                 :           0 :           call xgBlock_minmax(residuBlock,minResidu,dummy) ! Get minimum of true residuals
     663                 :             :           ! Compute effective residuals : res_eff = res * occ
     664                 :           0 :           call xgBlock_apply_diag(residuBlock,occBlock,1,Y=residu_eff%self)
     665                 :           0 :           call xgBlock_minmax(residu_eff%self,dummy,maxResidu) ! Get maximum of effective residuals
     666                 :             :         else
     667                 :           0 :           ABI_ERROR('Bad value of nbdbuf')
     668                 :             :         end if
     669                 :        7379 :         call timab(tim_nbdbuf,2,tsec)
     670                 :             :       end if
     671                 :             : 
     672   [ -  +  -  - ]:       16592 :       if (prtvol==5.and.xmpi_comm_rank(lobpcg%spacecom)==0) then
     673                 :           0 :         write(msg,'(6(a,i4),2(a,es16.6))') 'lobpcg | istep=',istep,'| isppol=',isppol,'| ikpt=',ikpt,&
     674                 :           0 :           & '| inonsc=',inonsc,'| iblock=',iblock,'| nline_done=',iline-1,'| minRes=',minResidu,'| maxRes=',maxResidu
     675                 :           0 :         call wrtout(std_out,msg,'PERS')
     676                 :             :       end if
     677                 :             : 
     678                 :             :       ! Save eigenvalues
     679                 :       16592 :       call timab(tim_copy,1,tsec)
     680                 :       16592 :       call xgBlock_setBlock(eigen,eigenBlock,blockdim,1,fcol=iblock)
     681                 :       16592 :       call xgBlock_copy(eigenvaluesN,eigenBlock)
     682                 :       16592 :       call timab(tim_copy,2,tsec)
     683                 :             : 
     684                 :             :       ! Save new X in X0
     685                 :       16592 :       call lobpcg_setX0(lobpcg,iblock)
     686                 :             : 
     687                 :             :       ! Copy previous BX into BX0 for previous block
     688         [ +  + ]:       20628 :       if ( nblock > 1 ) then
     689                 :       16560 :         call lobpcg_transferAX_BX(lobpcg,iblock)
     690                 :             :       end if
     691                 :             : 
     692                 :             :     end do !! End iblock loop
     693                 :             : 
     694                 :        4036 :     call xgBlock_reshape(eigen,blockdim*nblock,1)
     695                 :        4036 :     call xgBlock_reshape(residu,blockdim*nblock,1)
     696                 :        4036 :     call xgBlock_reshape(occ,blockdim*nblock,1)
     697                 :             : 
     698                 :        4036 :     call xg_free(eigenvalues3N)
     699                 :        4036 :     call xg_free(residu_eff)
     700                 :             : 
     701                 :        4036 :     skip = .false.
     702         [ -  + ]:        4036 :     if ( ierr /= 0 ) then
     703                 :           0 :       ABI_COMMENT("Some errors happened, so H|Psi> and S|Psi> are computed before leaving")
     704         [ #  # ]:           0 :       if ( lobpcg%paral_kgb == 1 ) then
     705                 :             :         call xgTransposer_constructor(lobpcg%xgTransposerAllX0,lobpcg%AllX0,lobpcg%AllX0ColsRows,nspinor,&
     706                 :           0 :           STATE_LINALG,TRANS_ALL2ALL,lobpcg%comm_rows,lobpcg%comm_cols,0,0,lobpcg%me_g0_fft)
     707                 :             :         call xgTransposer_copyConstructor(lobpcg%xgTransposerAllAX0,lobpcg%xgTransposerAllX0,&
     708                 :           0 :           lobpcg%AllAX0%self,lobpcg%AllAX0ColsRows,STATE_LINALG)
     709                 :             :       else
     710                 :           0 :         call xgBlock_setBlock(lobpcg%AllX0      , lobpcg%AllX0ColsRows , spacedim, lobpcg%neigenpairs)
     711                 :           0 :         call xgBlock_setBlock(lobpcg%AllAX0%self, lobpcg%AllAX0ColsRows, spacedim, lobpcg%neigenpairs)
     712                 :             :       end if
     713         [ #  # ]:           0 :       if (lobpcg%paral_kgb == 1) then
     714                 :           0 :         call timab(tim_transpose,1,tsec)
     715                 :           0 :         call xgTransposer_transpose(lobpcg%xgTransposerAllX0,STATE_COLSROWS)
     716                 :           0 :         lobpcg%xgTransposerAllAX0%state=STATE_COLSROWS
     717                 :           0 :         call timab(tim_transpose,2,tsec)
     718                 :             :       end if
     719                 :           0 :       call timab(tim_ax_v,1,tsec)
     720                 :           0 :       call getAX(lobpcg%AllX0ColsRows,lobpcg%AllAX0ColsRows)
     721                 :           0 :       call xgBlock_zero_im_g0(lobpcg%AllAX0ColsRows)
     722                 :           0 :       call timab(tim_ax_v,2,tsec)
     723         [ #  # ]:           0 :       if (lobpcg%paral_kgb == 1) then
     724                 :           0 :         call timab(tim_transpose,1,tsec)
     725                 :           0 :         call xgTransposer_transpose(lobpcg%xgTransposerAllX0,STATE_LINALG)
     726                 :           0 :         call xgTransposer_transpose(lobpcg%xgTransposerAllAX0,STATE_LINALG)
     727                 :           0 :         call timab(tim_transpose,2,tsec)
     728                 :             :       end if
     729                 :             : 
     730                 :           0 :       call timab(tim_ax_k,1,tsec)
     731                 :           0 :       call xgBlock_add_diag(lobpcg%AllX0,kin,nspinor,lobpcg%AllAX0%self)
     732                 :           0 :       call timab(tim_ax_k,2,tsec)
     733                 :             : 
     734                 :           0 :       call xgTransposer_free(lobpcg%xgTransposerAllX0)
     735                 :           0 :       call xgTransposer_free(lobpcg%xgTransposerAllAX0)
     736                 :             :       skip = .true.
     737                 :             :     end if
     738                 :             : 
     739                 :             :     if (.not.skip) then
     740                 :             : 
     741         [ +  + ]:        4036 :       if ( nblock > 1 ) then
     742                 :        4004 :         call timab(tim_cprj,1,tsec)
     743                 :        4004 :         call xg_init(cprj_work_all,space(cprjX0),rows(cprjX0),cols(cprjX0),comm(cprjX0))
     744                 :             :         ! cprj computation could be avoided, with MPI comm instead
     745                 :        4004 :         call xg_nonlop_getcprj(lobpcg%xg_nonlop,X0,cprjX0,cprj_work_all%self)
     746                 :        4004 :         call xg_free(cprj_work_all)
     747                 :        4004 :         call timab(tim_cprj,2,tsec)
     748                 :             :         call xg_Borthonormalize_cprj(lobpcg%xg_nonlop,X0,cprjX0,&
     749                 :        4004 :           & ierr,tim_Bortho_Xall,gpu_option,AX=lobpcg%AllAX0%self)
     750                 :             :         call xg_RayleighRitz_cprj(lobpcg%xg_nonlop,X0,cprjX0,lobpcg%AllAX0%self,eigen,ierr,&
     751                 :        4004 :           & lobpcg%prtvol,tim_RR_Xall,gpu_option,add_Anl=.True.)
     752                 :             :       end if
     753                 :             : 
     754                 :             :     end if
     755                 :             : 
     756         [ +  + ]:        4036 :     if ( lobpcg%paral_kgb == 1 ) then
     757                 :        2684 :       call xgTransposer_free(lobpcg%xgTransposerX)
     758                 :        2684 :       call xgTransposer_free(lobpcg%xgTransposerAX)
     759                 :        2684 :       call xgTransposer_free(lobpcg%xgTransposerW)
     760                 :        2684 :       call xgTransposer_free(lobpcg%xgTransposerAW)
     761                 :             :     end if
     762                 :             : 
     763         [ +  + ]:        4036 :     if (.not.lobpcg%xg_nonlop%paw) then
     764                 :         816 :       call timab(tim_enl,1,tsec)
     765                 :         816 :       call xg_init(cprj_work_all,space(cprjX0),rows(cprjX0),cols(cprjX0),comm(cprjX0))
     766                 :         816 :       call xg_nonlop_colwiseXHX(lobpcg%xg_nonlop,cprjX0,cprj_work_all%self,enl)
     767                 :         816 :       call xg_free(cprj_work_all)
     768                 :         816 :       call timab(tim_enl,2,tsec)
     769                 :             :     end if
     770                 :             : 
     771                 :        4036 :   end subroutine lobpcg_run_cprj
     772                 :             : 
     773                 :       16592 :   subroutine lobpcg_getX0(lobpcg,iblock)
     774                 :             : 
     775                 :             :     type(lobpcg_t) , intent(inout)  :: lobpcg
     776                 :             :     integer        , intent(in   )  :: iblock
     777                 :             :     type(xgBlock_t) :: Xtmp,cprjXtmp
     778                 :             :     integer :: blockdim
     779                 :             :     integer :: spacedim
     780                 :             :     integer :: cprjdim
     781                 :             :     integer :: blockdim_cprj
     782                 :             :     double precision :: tsec(2)
     783                 :             : 
     784                 :       16592 :     call timab(tim_copy,1,tsec)
     785                 :             : 
     786                 :       16592 :     blockdim = lobpcg%blockdim
     787                 :       16592 :     spacedim = lobpcg%spacedim
     788                 :             : 
     789                 :       16592 :     cprjdim       = lobpcg%cprjdim
     790                 :       16592 :     blockdim_cprj = lobpcg%blockdim_cprj
     791                 :             : 
     792                 :       16592 :     call xgBlock_setBlock(lobpcg%AllX0,Xtmp,spacedim,blockdim,fcol=(iblock-1)*blockdim+1)
     793                 :       16592 :     call xgBlock_copy(Xtmp,lobpcg%X)
     794                 :             : 
     795                 :       16592 :     call xgBlock_setBlock(lobpcg%AllcprjX0,cprjXtmp,cprjdim,blockdim_cprj,fcol=(iblock-1)*blockdim_cprj+1)
     796                 :       16592 :     call xgBlock_copy(cprjXtmp,lobpcg%cprjX)
     797                 :             : 
     798                 :       16592 :     call timab(tim_copy,2,tsec)
     799                 :             : 
     800                 :       16592 :   end subroutine lobpcg_getX0
     801                 :             : 
     802                 :             : 
     803                 :       12556 :   subroutine lobpcg_setPreviousX0(lobpcg,iblock)
     804                 :             : 
     805                 :             :     type(lobpcg_t) , intent(inout) :: lobpcg
     806                 :             :     integer        , intent(in   ) :: iblock
     807                 :             : 
     808         [ -  + ]:       12556 :     if (iblock<2) then
     809                 :           0 :       ABI_ERROR("iblock<2")
     810                 :             :     end if
     811                 :       12556 :     call xgBlock_setBlock(lobpcg%AllX0    ,lobpcg%X0    ,lobpcg%spacedim,(iblock-1)*lobpcg%blockdim)
     812                 :       12556 :     call xgBlock_setBlock(lobpcg%AllcprjX0,lobpcg%cprjX0,lobpcg%cprjdim ,(iblock-1)*lobpcg%blockdim_cprj)
     813                 :       12556 :   end subroutine lobpcg_setPreviousX0
     814                 :             : 
     815                 :       44954 :   subroutine lobpcg_orthoXwrtBlocks(lobpcg,var,cprjvar,iblock,cprj_work)
     816                 :             : 
     817                 :             :     type(lobpcg_t) , intent(inout) :: lobpcg
     818                 :             :     type(xgBlock_t), intent(inout) :: var
     819                 :             :     type(xgBlock_t), intent(inout) :: cprjvar
     820                 :             :     type(xgBlock_t), intent(inout) :: cprj_work
     821                 :             :     integer        , intent(in   ) :: iblock
     822                 :             :     integer :: previousBlock
     823                 :             :     integer :: blockdim
     824                 :             :     integer :: spacedim
     825                 :             :     integer :: space_buf
     826                 :             :     integer :: nspinor,cprjdim
     827                 :             :     type(xg_t) :: buffer
     828                 :             :     double precision :: tsec(2)
     829                 :             :     type(xgBlock_t) :: cprjX0_spinor,cprj_work_spinor
     830                 :             : 
     831                 :       44954 :     call timab(tim_ortho,1,tsec)
     832                 :             : 
     833         [ -  + ]:       44954 :     if (iblock<2) then
     834                 :           0 :       ABI_ERROR("iblock<2")
     835                 :             :     end if
     836                 :             : 
     837         [ -  + ]:       44954 :     if (cols(cprjvar)/=cols(cprj_work)) then
     838                 :           0 :       ABI_ERROR("cprjvar and cprj_work should have same number of columns")
     839                 :             :     end if
     840                 :       44954 :     blockdim = lobpcg%blockdim
     841                 :       44954 :     spacedim = lobpcg%spacedim
     842                 :       44954 :     previousBlock = (iblock-1)*lobpcg%blockdim
     843                 :             : 
     844                 :       44954 :     cprjdim = lobpcg%xg_nonlop%cprjdim
     845                 :       44954 :     nspinor = lobpcg%xg_nonlop%nspinor
     846                 :             : 
     847                 :       44954 :     space_buf = space(var)
     848         [ +  + ]:       44954 :     if (space(var)==SPACE_CR) then
     849                 :       20858 :       space_buf = SPACE_R
     850                 :             :     end if
     851                 :       44954 :     call xg_init(buffer,space_buf,previousBlock,blockdim,lobpcg%spacecom)
     852                 :             : 
     853                 :             :     ! buffer = X0^T*X
     854                 :       44954 :     call xgBlock_gemm('t','n',1.0d0,lobpcg%X0,var,0.d0,buffer%self,comm=lobpcg%spacecom)
     855                 :             : 
     856                 :             :     ! Add the nonlocal part if paw
     857         [ +  + ]:       44954 :     if (lobpcg%xg_nonlop%paw) then
     858                 :       37654 :       call xg_nonlop_getXSY(lobpcg%xg_nonlop,lobpcg%cprjX0,cprjvar,cprj_work,buffer%self)
     859                 :             :     end if
     860                 :             : 
     861                 :             :     ! sum all process contribution
     862                 :             :     ! X = - X0*(BX0^T*X) + X
     863                 :       44954 :     call xgBlock_gemm('n','n',-1.0d0,lobpcg%X0,buffer%self,1.0d0,var)
     864                 :             : 
     865                 :       44954 :     call xgBlock_zero(cprj_work)
     866                 :       44954 :     call xgBlock_reshape_spinor(cprj_work,cprj_work_spinor,nspinor,COLS2ROWS)
     867                 :       44954 :     call xgBlock_reshape_spinor(lobpcg%cprjX0,cprjX0_spinor,nspinor,COLS2ROWS)
     868                 :             :     call xgBlock_gemm_mpi_cyclic_permutation(cprjX0_spinor,buffer%self,cprj_work_spinor,&
     869                 :       44954 :       & lobpcg%xg_nonlop%me_band,blocksize=lobpcg%blockdim_cprj/nspinor,comm=lobpcg%xg_nonlop%comm_band)
     870                 :       44954 :     call xgBlock_saxpy(cprjvar,-1.0d0,cprj_work)
     871                 :             : 
     872                 :       44954 :     call xg_free(buffer)
     873                 :             : 
     874                 :       44954 :     call timab(tim_ortho,2,tsec)
     875                 :             : 
     876                 :       44954 :   end subroutine lobpcg_orthoXwrtBlocks
     877                 :             : 
     878                 :       16592 :   subroutine lobpcg_setX0(lobpcg,iblock)
     879                 :             : 
     880                 :             :     type(lobpcg_t)  , intent(inout) :: lobpcg
     881                 :             :     integer         , intent(in   ) :: iblock
     882                 :             :     type(xgBlock_t) :: Xtmp,cprjXtmp
     883                 :             :     integer :: blockdim
     884                 :             :     integer :: spacedim
     885                 :             :     integer :: cprjdim
     886                 :             :     integer :: blockdim_cprj
     887                 :             :     double precision :: tsec(2)
     888                 :             : 
     889                 :       16592 :     call timab(tim_copy,1,tsec)
     890                 :       16592 :     blockdim = lobpcg%blockdim
     891                 :       16592 :     spacedim = lobpcg%spacedim
     892                 :             : 
     893                 :       16592 :     cprjdim       = lobpcg%cprjdim
     894                 :       16592 :     blockdim_cprj = lobpcg%blockdim_cprj
     895                 :             : 
     896                 :             :     !X0(:,(iblock-1)*blockdim+1:iblock*blockdim) = lobpcg%XWP(:,lobpcg%X+1:lobpcg%X+blockdim)
     897                 :       16592 :     call xgBlock_setBlock(lobpcg%AllX0,Xtmp,spacedim,blockdim,fcol=(iblock-1)*blockdim+1)
     898                 :       16592 :     call xgBlock_copy(lobpcg%X,Xtmp)
     899                 :             : 
     900                 :       16592 :     call xgBlock_setBlock(lobpcg%AllcprjX0,cprjXtmp,cprjdim,blockdim_cprj,fcol=(iblock-1)*blockdim_cprj+1)
     901                 :       16592 :     call xgBlock_copy(lobpcg%cprjX,cprjXtmp)
     902                 :       16592 :     call timab(tim_copy,2,tsec)
     903                 :             : 
     904                 :       16592 :   end subroutine lobpcg_setX0
     905                 :             : 
     906                 :       16560 :   subroutine lobpcg_transferAX_BX(lobpcg,iblock)
     907                 :             : 
     908                 :             :     type(lobpcg_t), intent(inout) :: lobpcg
     909                 :             :     integer       , intent(in   ) :: iblock
     910                 :             :     type(xgBlock_t) :: CXtmp
     911                 :             :     integer :: firstcol
     912                 :             :     double precision :: tsec(2)
     913                 :             : 
     914                 :       16560 :     call timab(tim_copy,1,tsec)
     915                 :             : 
     916         [ -  + ]:       16560 :     if (iblock<1) then
     917                 :           0 :       ABI_ERROR("iblock<1")
     918                 :             :     end if
     919                 :             : 
     920                 :             :     ! iblock goes from 1 to nblock-1 included
     921                 :       16560 :     firstcol = (iblock-1)*lobpcg%blockdim+1  ! Start of each block
     922                 :             : 
     923                 :             :     ! AX
     924                 :       16560 :     call xg_setBlock(lobpcg%AllAX0,CXtmp,lobpcg%spacedim,lobpcg%blockdim,fcol=firstcol)
     925                 :       16560 :     call xgBlock_copy(lobpcg%AX,CXtmp)
     926                 :             : 
     927                 :       16560 :     call timab(tim_copy,2,tsec)
     928                 :             : 
     929                 :       16560 :   end subroutine lobpcg_transferAX_BX
     930                 :             : 
     931                 :        8072 :   subroutine lobpcg_free(lobpcg)
     932                 :             : 
     933                 :             :     type(lobpcg_t), intent(inout) :: lobpcg
     934                 :             : 
     935                 :        8072 :     call xg_free(lobpcg%XWP)
     936                 :        8072 :     call xg_free(lobpcg%AXWP)
     937                 :        8072 :     call xg_free(lobpcg%cprjXWP)
     938                 :        8072 :     call xg_free(lobpcg%cprj_work)
     939                 :        8072 :     call xg_free(lobpcg%cprj_work2)
     940                 :        8072 :     call xg_free(lobpcg%AllAX0)
     941                 :             : 
     942                 :        8072 :   end subroutine lobpcg_free
     943                 :             : 
     944   [ #  #  #  #  :           0 : end module m_lobpcg2_cprj
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     945                 :             : !!***
        

Generated by: LCOV version 2.3-1