Adjusted handling block size for FM matrices (#3795)

This commit is contained in:
Hans Pabst 2024-12-10 11:41:06 +01:00 committed by GitHub
parent dbaa6fc110
commit e7c81ba798
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 67 additions and 49 deletions

View file

@ -58,7 +58,7 @@ CONTAINS
COMPLEX(KIND=dp), DIMENSION(:), POINTER :: work COMPLEX(KIND=dp), DIMENSION(:), POINTER :: work
COMPLEX(KIND=dp), DIMENSION(:, :), & COMPLEX(KIND=dp), DIMENSION(:, :), &
POINTER :: m POINTER :: m
INTEGER :: handle, info, liwork, & INTEGER :: handle, info, liwork, &
lrwork, lwork, n lrwork, lwork, n
INTEGER, DIMENSION(:), POINTER :: iwork INTEGER, DIMENSION(:), POINTER :: iwork
@ -66,7 +66,7 @@ CONTAINS
#if defined(__parallel) #if defined(__parallel)
INTEGER, DIMENSION(9) :: descm, descv INTEGER, DIMENSION(9) :: descm, descv
COMPLEX(KIND=dp), DIMENSION(:, :), & COMPLEX(KIND=dp), DIMENSION(:, :), &
POINTER :: v POINTER :: v
#if defined (__HAS_IEEE_EXCEPTIONS) #if defined (__HAS_IEEE_EXCEPTIONS)
LOGICAL, DIMENSION(5) :: halt LOGICAL, DIMENSION(5) :: halt
#endif #endif

View file

@ -678,8 +678,8 @@ CONTAINS
! Diagonalise the symmetric n by n matrix using the LAPACK library. ! Diagonalise the symmetric n by n matrix using the LAPACK library.
TYPE(cp_fm_type), INTENT(IN) :: matrix TYPE(cp_fm_type), INTENT(IN) :: matrix
TYPE(cp_fm_type), OPTIONAL, INTENT(IN) :: eigenvectors TYPE(cp_fm_type), OPTIONAL, INTENT(IN) :: eigenvectors
REAL(KIND=dp), OPTIONAL, INTENT(IN) :: work_syevx REAL(KIND=dp), OPTIONAL, INTENT(IN) :: work_syevx
INTEGER, INTENT(IN), OPTIONAL :: neig INTEGER, INTENT(IN), OPTIONAL :: neig
REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: eigenvalues REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: eigenvalues
@ -925,7 +925,7 @@ CONTAINS
CHARACTER(LEN=2*default_string_length) :: message CHARACTER(LEN=2*default_string_length) :: message
INTEGER :: handle, n, m, myinfo, lwork INTEGER :: handle, n, m, myinfo, lwork
REAL(KIND=dp), DIMENSION(:, :), POINTER :: a REAL(KIND=dp), DIMENSION(:, :), POINTER :: a
TYPE(cp_fm_type) :: matrix_lu TYPE(cp_fm_type) :: matrix_lu
REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: work REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: work
#if defined(__parallel) #if defined(__parallel)
@ -1043,7 +1043,7 @@ CONTAINS
! - Creation (29.03.1999, Matthias Krack) ! - Creation (29.03.1999, Matthias Krack)
! - Parallelised using BLACS and ScaLAPACK (06.06.2001,MK) ! - Parallelised using BLACS and ScaLAPACK (06.06.2001,MK)
TYPE(cp_fm_type), INTENT(IN) :: matrix, work TYPE(cp_fm_type), INTENT(IN) :: matrix, work
REAL(KIND=dp), INTENT(IN) :: exponent, threshold REAL(KIND=dp), INTENT(IN) :: exponent, threshold
INTEGER, INTENT(OUT) :: n_dependent INTEGER, INTENT(OUT) :: n_dependent
LOGICAL, INTENT(IN), OPTIONAL :: verbose LOGICAL, INTENT(IN), OPTIONAL :: verbose
@ -1212,7 +1212,7 @@ CONTAINS
! - Creation (07.10.2002, Martin Fengler) ! - Creation (07.10.2002, Martin Fengler)
! - Cosmetics (05.04.06, MK) ! - Cosmetics (05.04.06, MK)
TYPE(cp_fm_type), INTENT(IN) :: eigenvectors, matrix TYPE(cp_fm_type), INTENT(IN) :: eigenvectors, matrix
REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: eigval REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: eigval
INTEGER, INTENT(IN) :: start_sec_block INTEGER, INTENT(IN) :: start_sec_block
REAL(KIND=dp), INTENT(IN) :: thresh REAL(KIND=dp), INTENT(IN) :: thresh
@ -1220,11 +1220,11 @@ CONTAINS
CHARACTER(len=*), PARAMETER :: routineN = 'cp_fm_block_jacobi' CHARACTER(len=*), PARAMETER :: routineN = 'cp_fm_block_jacobi'
INTEGER :: handle INTEGER :: handle
REAL(KIND=dp), DIMENSION(:, :), POINTER :: a, ev REAL(KIND=dp), DIMENSION(:, :), POINTER :: a, ev
REAL(KIND=dp) :: tan_theta, tau, c, s REAL(KIND=dp) :: tan_theta, tau, c, s
INTEGER :: q, p, N INTEGER :: q, p, N
REAL(KIND=dp), DIMENSION(:), ALLOCATABLE :: c_ip REAL(KIND=dp), DIMENSION(:), ALLOCATABLE :: c_ip
#if defined(__parallel) #if defined(__parallel)
TYPE(cp_blacs_env_type), POINTER :: context TYPE(cp_blacs_env_type), POINTER :: context
@ -1232,7 +1232,7 @@ CONTAINS
INTEGER :: myprow, mypcol, nprow, npcol, block_dim_row, block_dim_col, & INTEGER :: myprow, mypcol, nprow, npcol, block_dim_row, block_dim_col, &
info, ev_row_block_size, iam, mynumrows, mype, npe, & info, ev_row_block_size, iam, mynumrows, mype, npe, &
q_loc q_loc
REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: a_loc, ev_loc REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: a_loc, ev_loc
INTEGER, DIMENSION(9) :: desca, descz, desc_a_block, & INTEGER, DIMENSION(9) :: desca, descz, desc_a_block, &
desc_ev_loc desc_ev_loc
TYPE(mp_comm_type):: allgrp TYPE(mp_comm_type):: allgrp

View file

@ -18,8 +18,8 @@ MODULE cp_fm_struct
cp_logger_get_default_unit_nr,& cp_logger_get_default_unit_nr,&
cp_logger_type,& cp_logger_type,&
cp_to_string cp_to_string
USE kinds, ONLY: dp USE machine, ONLY: m_cpuid_vlen,&
USE machine, ONLY: m_flush m_flush
USE message_passing, ONLY: mp_para_env_release,& USE message_passing, ONLY: mp_para_env_release,&
mp_para_env_type mp_para_env_type
#include "../base/base_uses.f90" #include "../base/base_uses.f90"
@ -34,8 +34,8 @@ MODULE cp_fm_struct
! consider using #ifdefs to give them the optimal values ! consider using #ifdefs to give them the optimal values
! these can be changed using scf_control ! these can be changed using scf_control
! *** these are used by default ! *** these are used by default
INTEGER, PRIVATE :: optimal_blacs_col_block_size = 32 INTEGER, PRIVATE :: optimal_blacs_col_block_size = 64
INTEGER, PRIVATE :: optimal_blacs_row_block_size = 32 INTEGER, PRIVATE :: optimal_blacs_row_block_size = 64
LOGICAL, PRIVATE :: force_block_size = .FALSE. LOGICAL, PRIVATE :: force_block_size = .FALSE.
PUBLIC :: cp_fm_struct_type, cp_fm_struct_p_type PUBLIC :: cp_fm_struct_type, cp_fm_struct_p_type
@ -142,7 +142,7 @@ CONTAINS
LOGICAL, OPTIONAL, INTENT(in) :: square_blocks LOGICAL, OPTIONAL, INTENT(in) :: square_blocks
LOGICAL, OPTIONAL, INTENT(in) :: force_block LOGICAL, OPTIONAL, INTENT(in) :: force_block
INTEGER :: dumblock, i INTEGER :: i, nmax_block, vlen
#if defined(__parallel) #if defined(__parallel)
INTEGER :: iunit, stat INTEGER :: iunit, stat
INTEGER, EXTERNAL :: numroc INTEGER, EXTERNAL :: numroc
@ -153,14 +153,13 @@ CONTAINS
ALLOCATE (fmstruct) ALLOCATE (fmstruct)
fmstruct%nrow_block = optimal_blacs_row_block_size
fmstruct%ncol_block = optimal_blacs_col_block_size
IF (.NOT. PRESENT(template_fmstruct)) THEN IF (.NOT. PRESENT(template_fmstruct)) THEN
CPASSERT(PRESENT(context)) CPASSERT(PRESENT(context))
CPASSERT(PRESENT(nrow_global)) CPASSERT(PRESENT(nrow_global))
CPASSERT(PRESENT(ncol_global)) CPASSERT(PRESENT(ncol_global))
fmstruct%local_leading_dimension = 1 fmstruct%local_leading_dimension = 1
fmstruct%nrow_block = 0 ! populate default later
fmstruct%ncol_block = 0 ! populate default later
ELSE ELSE
fmstruct%context => template_fmstruct%context fmstruct%context => template_fmstruct%context
fmstruct%para_env => template_fmstruct%para_env fmstruct%para_env => template_fmstruct%para_env
@ -174,8 +173,16 @@ CONTAINS
template_fmstruct%local_leading_dimension template_fmstruct%local_leading_dimension
END IF END IF
my_force_block = force_block_size ! allow to request default block size (zero or negative value)
IF (PRESENT(force_block)) my_force_block = force_block IF (PRESENT(nrow_block)) fmstruct%nrow_block = nrow_block
IF (PRESENT(ncol_block)) fmstruct%ncol_block = ncol_block
IF (0 >= fmstruct%nrow_block) THEN
fmstruct%nrow_block = optimal_blacs_row_block_size
END IF
IF (0 >= fmstruct%ncol_block) THEN
fmstruct%ncol_block = optimal_blacs_col_block_size
END IF
CPASSERT(0 < fmstruct%nrow_block .AND. 0 < fmstruct%ncol_block)
IF (PRESENT(context)) THEN IF (PRESENT(context)) THEN
fmstruct%context => context fmstruct%context => context
@ -193,28 +200,24 @@ CONTAINS
fmstruct%ncol_global = ncol_global fmstruct%ncol_global = ncol_global
END IF END IF
! try to avoid small left-over blocks (anyway naive) my_force_block = force_block_size
IF (PRESENT(nrow_block)) THEN IF (PRESENT(force_block)) my_force_block = force_block
IF (nrow_block > 0) & ! allows setting the number of blocks to -1 to explicitly set to auto
fmstruct%nrow_block = nrow_block
END IF
IF (.NOT. my_force_block) THEN IF (.NOT. my_force_block) THEN
dumblock = CEILING(REAL(fmstruct%nrow_global, KIND=dp)/ & vlen = m_cpuid_vlen()
REAL(fmstruct%context%num_pe(1), KIND=dp)) nmax_block = (fmstruct%nrow_global + fmstruct%context%num_pe(1) - 1)/ &
fmstruct%nrow_block = MAX(1, MIN(fmstruct%nrow_block, dumblock)) (fmstruct%context%num_pe(1))*fmstruct%context%num_pe(1)
END IF IF (1 < vlen) nmax_block = nmax_block/vlen*vlen ! floor
IF (PRESENT(ncol_block)) THEN fmstruct%nrow_block = MAX(MIN(fmstruct%nrow_block, nmax_block), 1)
IF (ncol_block > 0) & ! allows setting the number of blocks to -1 to explicitly set to auto
fmstruct%ncol_block = ncol_block nmax_block = (fmstruct%ncol_global + fmstruct%context%num_pe(2) - 1)/ &
END IF (fmstruct%context%num_pe(1))*fmstruct%context%num_pe(2)
IF (.NOT. my_force_block) THEN IF (1 < vlen) nmax_block = nmax_block/vlen*vlen ! floor
dumblock = CEILING(REAL(fmstruct%ncol_global, KIND=dp)/ & fmstruct%ncol_block = MAX(MIN(fmstruct%ncol_block, nmax_block), 1)
REAL(fmstruct%context%num_pe(2), KIND=dp))
fmstruct%ncol_block = MAX(1, MIN(fmstruct%ncol_block, dumblock))
END IF END IF
! square matrix -> square blocks (otherwise some op fail) ! square matrix -> square blocks (otherwise, e.g., PDPOTRF fails)
my_square_blocks = fmstruct%nrow_global == fmstruct%ncol_global my_square_blocks = fmstruct%nrow_global == fmstruct%ncol_global
! however, requesting non-square blocks takes precedence
IF (PRESENT(square_blocks)) my_square_blocks = square_blocks IF (PRESENT(square_blocks)) my_square_blocks = square_blocks
IF (my_square_blocks) THEN IF (my_square_blocks) THEN
fmstruct%nrow_block = MIN(fmstruct%nrow_block, fmstruct%ncol_block) fmstruct%nrow_block = MIN(fmstruct%nrow_block, fmstruct%ncol_block)
@ -610,8 +613,19 @@ CONTAINS
INTEGER, INTENT(IN), OPTIONAL :: nrow_block, ncol_block INTEGER, INTENT(IN), OPTIONAL :: nrow_block, ncol_block
LOGICAL, INTENT(IN), OPTIONAL :: force_block LOGICAL, INTENT(IN), OPTIONAL :: force_block
IF (PRESENT(ncol_block)) optimal_blacs_col_block_size = ncol_block INTEGER :: vlen
IF (PRESENT(nrow_block)) optimal_blacs_row_block_size = nrow_block
vlen = m_cpuid_vlen()
IF (PRESENT(ncol_block)) THEN
IF (0 < ncol_block) THEN
optimal_blacs_col_block_size = (ncol_block + vlen - 1)/vlen*vlen
END IF
END IF
IF (PRESENT(nrow_block)) THEN
IF (0 < nrow_block) THEN
optimal_blacs_row_block_size = (nrow_block + vlen - 1)/vlen*vlen
END IF
END IF
IF (PRESENT(force_block)) force_block_size = force_block IF (PRESENT(force_block)) force_block_size = force_block
END SUBROUTINE cp_fm_struct_config END SUBROUTINE cp_fm_struct_config

View file

@ -29,6 +29,8 @@ MODULE input_cp2k_global
USE cp_fm_elpa, ONLY: elpa_kernel_descriptions,& USE cp_fm_elpa, ONLY: elpa_kernel_descriptions,&
elpa_kernel_ids,& elpa_kernel_ids,&
elpa_kernel_names elpa_kernel_names
USE cp_fm_struct, ONLY: cp_fm_struct_get_ncol_block,&
cp_fm_struct_get_nrow_block
USE cp_output_handling, ONLY: add_last_numeric,& USE cp_output_handling, ONLY: add_last_numeric,&
cp_print_key_section_create,& cp_print_key_section_create,&
debug_print_level,& debug_print_level,&
@ -283,7 +285,7 @@ CONTAINS
"larger allowed grids, or grids that more precisely match a given cutoff. "// & "larger allowed grids, or grids that more precisely match a given cutoff. "// &
"IMPORTANT NOTE: in this case, the actual grids used in CP2K depends on the FFT library. "// & "IMPORTANT NOTE: in this case, the actual grids used in CP2K depends on the FFT library. "// &
"A change of FFT library must therefore be considered equivalent to a change of basis, "// & "A change of FFT library must therefore be considered equivalent to a change of basis, "// &
"which implies a change of total energy. ", & "which implies a change of total energy.", &
usage="EXTENDED_FFT_LENGTHS", & usage="EXTENDED_FFT_LENGTHS", &
default_l_val=.FALSE., lone_keyword_l_val=.TRUE.) default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
CALL section_add_keyword(section, keyword) CALL section_add_keyword(section, keyword)
@ -419,7 +421,7 @@ CONTAINS
CALL keyword_release(keyword) CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="TRACE", & CALL keyword_create(keyword, __LOCATION__, name="TRACE", &
description="If a debug trace of the execution of the program should be written ", & description="If a debug trace of the execution of the program should be written", &
usage="TRACE", & usage="TRACE", &
default_l_val=.FALSE., lone_keyword_l_val=.TRUE.) default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
CALL section_add_keyword(section, keyword) CALL section_add_keyword(section, keyword)
@ -490,7 +492,7 @@ CONTAINS
CALL keyword_create(keyword, __LOCATION__, name="SAVE_MEM", & CALL keyword_create(keyword, __LOCATION__, name="SAVE_MEM", &
description="Some sections of the input structure are deallocated when not needed,"// & description="Some sections of the input structure are deallocated when not needed,"// &
" and reallocated only when used. This reduces the required maximum memory ", & " and reallocated only when used. This reduces the required maximum memory.", &
usage="SAVE_MEM", & usage="SAVE_MEM", &
default_l_val=.FALSE., lone_keyword_l_val=.TRUE.) default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
CALL section_add_keyword(section, keyword) CALL section_add_keyword(section, keyword)
@ -639,21 +641,23 @@ CONTAINS
CALL keyword_create(keyword, __LOCATION__, name="NROW_BLOCKS", & CALL keyword_create(keyword, __LOCATION__, name="NROW_BLOCKS", &
description="Defines the number of rows per scalapack block in "// & description="Defines the number of rows per scalapack block in "// &
"the creation of block cyclic dense matrices ", & "the creation of block cyclic dense matrices. "// &
default_i_val=64) "Use an internal default if zero or negative.", &
default_i_val=cp_fm_struct_get_nrow_block())
CALL section_add_keyword(section, keyword) CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword) CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="NCOL_BLOCKS", & CALL keyword_create(keyword, __LOCATION__, name="NCOL_BLOCKS", &
description="Defines the number of columns per scalapack block in "// & description="Defines the number of columns per scalapack block in "// &
"the creation of vlock cyclic dense matrices ", & "the creation of vlock cyclic dense matrices. "// &
default_i_val=64) "Use an internal default if zero or negative.", &
default_i_val=cp_fm_struct_get_ncol_block())
CALL section_add_keyword(section, keyword) CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword) CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="FORCE_BLOCK_SIZE", & CALL keyword_create(keyword, __LOCATION__, name="FORCE_BLOCK_SIZE", &
description="Ensure for small matrices that the layout is compatible "// & description="Ensure for small matrices that the layout is compatible "// &
"with bigger ones, i.e. no subdivision is performed (can break LAPACK!!!).", & "with bigger ones, i.e. no subdivision is performed (can break LAPACK).", &
usage="FORCE_BLOCK_SIZE", & usage="FORCE_BLOCK_SIZE", &
default_l_val=.FALSE., lone_keyword_l_val=.TRUE.) default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
CALL section_add_keyword(section, keyword) CALL section_add_keyword(section, keyword)
@ -737,7 +741,7 @@ CONTAINS
description="Controls how to perform redistribution when ELPA is used for diagonalization. "// & description="Controls how to perform redistribution when ELPA is used for diagonalization. "// &
"By default, redistribution is always performed using the defined rules. "// & "By default, redistribution is always performed using the defined rules. "// &
"By turning off this keyword, matrices are redistributed only to prevent crashes in the ELPA "// & "By turning off this keyword, matrices are redistributed only to prevent crashes in the ELPA "// &
"library which happens when the original matrix is distributed over too many processors. ", & "library which happens when the original matrix is distributed over too many processors.", &
usage="ELPA_FORCE_REDISTRIBUTE", type_of_var=logical_t, & usage="ELPA_FORCE_REDISTRIBUTE", type_of_var=logical_t, &
default_l_val=.TRUE., lone_keyword_l_val=.TRUE.) default_l_val=.TRUE., lone_keyword_l_val=.TRUE.)
CALL section_add_keyword(section, keyword) CALL section_add_keyword(section, keyword)