diff --git a/src/fm/cp_cfm_diag.F b/src/fm/cp_cfm_diag.F index a9fe65d17f..2214592985 100644 --- a/src/fm/cp_cfm_diag.F +++ b/src/fm/cp_cfm_diag.F @@ -58,7 +58,7 @@ CONTAINS COMPLEX(KIND=dp), DIMENSION(:), POINTER :: work COMPLEX(KIND=dp), DIMENSION(:, :), & - POINTER :: m + POINTER :: m INTEGER :: handle, info, liwork, & lrwork, lwork, n INTEGER, DIMENSION(:), POINTER :: iwork @@ -66,7 +66,7 @@ CONTAINS #if defined(__parallel) INTEGER, DIMENSION(9) :: descm, descv COMPLEX(KIND=dp), DIMENSION(:, :), & - POINTER :: v + POINTER :: v #if defined (__HAS_IEEE_EXCEPTIONS) LOGICAL, DIMENSION(5) :: halt #endif diff --git a/src/fm/cp_fm_diag.F b/src/fm/cp_fm_diag.F index 392c8ecb20..e7d0f47178 100644 --- a/src/fm/cp_fm_diag.F +++ b/src/fm/cp_fm_diag.F @@ -678,8 +678,8 @@ CONTAINS ! Diagonalise the symmetric n by n matrix using the LAPACK library. - TYPE(cp_fm_type), INTENT(IN) :: matrix - TYPE(cp_fm_type), OPTIONAL, INTENT(IN) :: eigenvectors + TYPE(cp_fm_type), INTENT(IN) :: matrix + TYPE(cp_fm_type), OPTIONAL, INTENT(IN) :: eigenvectors REAL(KIND=dp), OPTIONAL, INTENT(IN) :: work_syevx INTEGER, INTENT(IN), OPTIONAL :: neig REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: eigenvalues @@ -925,7 +925,7 @@ CONTAINS CHARACTER(LEN=2*default_string_length) :: message INTEGER :: handle, n, m, myinfo, lwork REAL(KIND=dp), DIMENSION(:, :), POINTER :: a - TYPE(cp_fm_type) :: matrix_lu + TYPE(cp_fm_type) :: matrix_lu REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: work #if defined(__parallel) @@ -1043,7 +1043,7 @@ CONTAINS ! - Creation (29.03.1999, Matthias Krack) ! - 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 INTEGER, INTENT(OUT) :: n_dependent LOGICAL, INTENT(IN), OPTIONAL :: verbose @@ -1212,7 +1212,7 @@ CONTAINS ! - Creation (07.10.2002, Martin Fengler) ! - 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 INTEGER, INTENT(IN) :: start_sec_block REAL(KIND=dp), INTENT(IN) :: thresh @@ -1220,11 +1220,11 @@ CONTAINS CHARACTER(len=*), PARAMETER :: routineN = 'cp_fm_block_jacobi' INTEGER :: handle - REAL(KIND=dp), DIMENSION(:, :), POINTER :: a, ev + REAL(KIND=dp), DIMENSION(:, :), POINTER :: a, ev REAL(KIND=dp) :: tan_theta, tau, c, s INTEGER :: q, p, N - REAL(KIND=dp), DIMENSION(:), ALLOCATABLE :: c_ip + REAL(KIND=dp), DIMENSION(:), ALLOCATABLE :: c_ip #if defined(__parallel) TYPE(cp_blacs_env_type), POINTER :: context @@ -1232,7 +1232,7 @@ CONTAINS INTEGER :: myprow, mypcol, nprow, npcol, block_dim_row, block_dim_col, & info, ev_row_block_size, iam, mynumrows, mype, npe, & 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, & desc_ev_loc TYPE(mp_comm_type):: allgrp diff --git a/src/fm/cp_fm_struct.F b/src/fm/cp_fm_struct.F index cc91c0d6dd..c6c1a27275 100644 --- a/src/fm/cp_fm_struct.F +++ b/src/fm/cp_fm_struct.F @@ -18,8 +18,8 @@ MODULE cp_fm_struct cp_logger_get_default_unit_nr,& cp_logger_type,& cp_to_string - USE kinds, ONLY: dp - USE machine, ONLY: m_flush + USE machine, ONLY: m_cpuid_vlen,& + m_flush USE message_passing, ONLY: mp_para_env_release,& mp_para_env_type #include "../base/base_uses.f90" @@ -34,8 +34,8 @@ MODULE cp_fm_struct ! consider using #ifdefs to give them the optimal values ! these can be changed using scf_control ! *** these are used by default - INTEGER, PRIVATE :: optimal_blacs_col_block_size = 32 - INTEGER, PRIVATE :: optimal_blacs_row_block_size = 32 + INTEGER, PRIVATE :: optimal_blacs_col_block_size = 64 + INTEGER, PRIVATE :: optimal_blacs_row_block_size = 64 LOGICAL, PRIVATE :: force_block_size = .FALSE. 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) :: force_block - INTEGER :: dumblock, i + INTEGER :: i, nmax_block, vlen #if defined(__parallel) INTEGER :: iunit, stat INTEGER, EXTERNAL :: numroc @@ -153,14 +153,13 @@ CONTAINS ALLOCATE (fmstruct) - fmstruct%nrow_block = optimal_blacs_row_block_size - fmstruct%ncol_block = optimal_blacs_col_block_size - IF (.NOT. PRESENT(template_fmstruct)) THEN CPASSERT(PRESENT(context)) CPASSERT(PRESENT(nrow_global)) CPASSERT(PRESENT(ncol_global)) fmstruct%local_leading_dimension = 1 + fmstruct%nrow_block = 0 ! populate default later + fmstruct%ncol_block = 0 ! populate default later ELSE fmstruct%context => template_fmstruct%context fmstruct%para_env => template_fmstruct%para_env @@ -174,8 +173,16 @@ CONTAINS template_fmstruct%local_leading_dimension END IF - my_force_block = force_block_size - IF (PRESENT(force_block)) my_force_block = force_block + ! allow to request default block size (zero or negative value) + 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 fmstruct%context => context @@ -193,28 +200,24 @@ CONTAINS fmstruct%ncol_global = ncol_global END IF - ! try to avoid small left-over blocks (anyway naive) - IF (PRESENT(nrow_block)) THEN - IF (nrow_block > 0) & ! allows setting the number of blocks to -1 to explicitly set to auto - fmstruct%nrow_block = nrow_block - END IF + my_force_block = force_block_size + IF (PRESENT(force_block)) my_force_block = force_block IF (.NOT. my_force_block) THEN - dumblock = CEILING(REAL(fmstruct%nrow_global, KIND=dp)/ & - REAL(fmstruct%context%num_pe(1), KIND=dp)) - fmstruct%nrow_block = MAX(1, MIN(fmstruct%nrow_block, dumblock)) - END IF - IF (PRESENT(ncol_block)) THEN - IF (ncol_block > 0) & ! allows setting the number of blocks to -1 to explicitly set to auto - fmstruct%ncol_block = ncol_block - END IF - IF (.NOT. my_force_block) THEN - dumblock = CEILING(REAL(fmstruct%ncol_global, KIND=dp)/ & - REAL(fmstruct%context%num_pe(2), KIND=dp)) - fmstruct%ncol_block = MAX(1, MIN(fmstruct%ncol_block, dumblock)) + vlen = m_cpuid_vlen() + nmax_block = (fmstruct%nrow_global + fmstruct%context%num_pe(1) - 1)/ & + (fmstruct%context%num_pe(1))*fmstruct%context%num_pe(1) + IF (1 < vlen) nmax_block = nmax_block/vlen*vlen ! floor + fmstruct%nrow_block = MAX(MIN(fmstruct%nrow_block, nmax_block), 1) + + nmax_block = (fmstruct%ncol_global + fmstruct%context%num_pe(2) - 1)/ & + (fmstruct%context%num_pe(1))*fmstruct%context%num_pe(2) + IF (1 < vlen) nmax_block = nmax_block/vlen*vlen ! floor + fmstruct%ncol_block = MAX(MIN(fmstruct%ncol_block, nmax_block), 1) 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 + ! however, requesting non-square blocks takes precedence IF (PRESENT(square_blocks)) my_square_blocks = square_blocks IF (my_square_blocks) THEN fmstruct%nrow_block = MIN(fmstruct%nrow_block, fmstruct%ncol_block) @@ -610,8 +613,19 @@ CONTAINS INTEGER, INTENT(IN), OPTIONAL :: nrow_block, ncol_block LOGICAL, INTENT(IN), OPTIONAL :: force_block - IF (PRESENT(ncol_block)) optimal_blacs_col_block_size = ncol_block - IF (PRESENT(nrow_block)) optimal_blacs_row_block_size = nrow_block + INTEGER :: vlen + + 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 END SUBROUTINE cp_fm_struct_config diff --git a/src/input_cp2k_global.F b/src/input_cp2k_global.F index 595b9cbc3c..7c026d0632 100644 --- a/src/input_cp2k_global.F +++ b/src/input_cp2k_global.F @@ -29,6 +29,8 @@ MODULE input_cp2k_global USE cp_fm_elpa, ONLY: elpa_kernel_descriptions,& elpa_kernel_ids,& 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,& cp_print_key_section_create,& debug_print_level,& @@ -283,7 +285,7 @@ CONTAINS "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. "// & "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", & default_l_val=.FALSE., lone_keyword_l_val=.TRUE.) CALL section_add_keyword(section, keyword) @@ -419,7 +421,7 @@ CONTAINS CALL keyword_release(keyword) 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", & default_l_val=.FALSE., lone_keyword_l_val=.TRUE.) CALL section_add_keyword(section, keyword) @@ -490,7 +492,7 @@ CONTAINS CALL keyword_create(keyword, __LOCATION__, name="SAVE_MEM", & 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", & default_l_val=.FALSE., lone_keyword_l_val=.TRUE.) CALL section_add_keyword(section, keyword) @@ -639,21 +641,23 @@ CONTAINS CALL keyword_create(keyword, __LOCATION__, name="NROW_BLOCKS", & description="Defines the number of rows per scalapack block in "// & - "the creation of block cyclic dense matrices ", & - default_i_val=64) + "the creation of block cyclic dense matrices. "// & + "Use an internal default if zero or negative.", & + default_i_val=cp_fm_struct_get_nrow_block()) CALL section_add_keyword(section, keyword) CALL keyword_release(keyword) CALL keyword_create(keyword, __LOCATION__, name="NCOL_BLOCKS", & description="Defines the number of columns per scalapack block in "// & - "the creation of vlock cyclic dense matrices ", & - default_i_val=64) + "the creation of vlock cyclic dense matrices. "// & + "Use an internal default if zero or negative.", & + default_i_val=cp_fm_struct_get_ncol_block()) CALL section_add_keyword(section, keyword) CALL keyword_release(keyword) CALL keyword_create(keyword, __LOCATION__, name="FORCE_BLOCK_SIZE", & 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", & default_l_val=.FALSE., lone_keyword_l_val=.TRUE.) CALL section_add_keyword(section, keyword) @@ -737,7 +741,7 @@ CONTAINS description="Controls how to perform redistribution when ELPA is used for diagonalization. "// & "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 "// & - "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, & default_l_val=.TRUE., lone_keyword_l_val=.TRUE.) CALL section_add_keyword(section, keyword)