available_solvers.F90 4.12 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
!--------------------------------------------------------------------------------
! Copyright (c) 2016 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
! This file is part of FLEUR and available as free software under the conditions
! of the MIT license as expressed in the LICENSE file in more detail.
!--------------------------------------------------------------------------------

MODULE m_available_solvers
    IMPLICIT NONE
! list of constants indicating the different solvers
! the parameters are set to negative values to indicate that a particular solver is not compiled
! -solvers with numbers below 100 expect a non-distributed matrix
! -solvers with numbers 100-199 expect a distributed (scalapack-type) matrix
! -solvers with numbers higher than 200 can handle both
#ifdef CPP_ELPA
  INTEGER,PARAMETER:: diag_elpa=101
#else
  INTEGER,PARAMETER:: diag_elpa=-101
#endif
#ifdef CPP_ELEMENTAL
  INTEGER,PARAMETER:: diag_elemental=102
#else
  INTEGER,PARAMETER:: diag_elemental=-102
#endif
#ifdef CPP_SCALAPACK
  INTEGER,PARAMETER:: diag_scalapack=103
#else
  INTEGER,PARAMETER:: diag_scalapack=-103
#endif
#ifdef CPP_MAGMA
  INTEGER,PARAMETER:: diag_magma=6
#else
  INTEGER,PARAMETER:: diag_magma=-6
#endif
#ifdef CPP_CHASE
  INTEGER,PARAMETER:: diag_chase=7
#else
  INTEGER,PARAMETER:: diag_chase=-7
#endif
#ifdef CPP_CUSOLVER
  INTEGER,PARAMETER:: diag_cusolver=8
#else
  INTEGER,PARAMETER:: diag_cusolver=-8
#endif
  
  INTEGER,PARAMETER:: diag_lapack=4
#ifdef CPP_ELPA_ONENODE
  INTEGER,PARAMETER:: diag_elpa_1node=14
#else
  INTEGER,PARAMETER:: diag_elpa_1node=-14
#endif 
  INTEGER,PARAMETER:: diag_debugout=201
  
  INTEGER,PARAMETER::diag_all_solver(9)=(/diag_elpa,diag_elemental,diag_scalapack,diag_magma,diag_chase,diag_cusolver,diag_lapack,diag_elpa_1node,diag_debugout/)
  
CONTAINS

  LOGICAL FUNCTION parallel_solver_available()
    parallel_solver_available=ANY(diag_all_solver>100)
  END FUNCTION parallel_solver_available

  FUNCTION select_solver(suggested_solver,parallel) RESULT(diag_solver)
    USE m_juDFT
    LOGICAL,INTENT(IN):: parallel
    INTEGER,INTENT(in):: suggested_solver
    INTEGER           :: diag_solver
    diag_solver=-99

    diag_solver=suggested_solver

    IF (suggested_solver==0) THEN
       !Determine the default solver
       IF (parallel) THEN
          diag_solver=MINVAL(diag_all_solver,mask=diag_all_solver>100)
       ELSE
          diag_solver=MINVAL(diag_all_solver,mask=diag_all_solver>0)
       ENDIF
       
       !check if a special solver was requested
       IF (TRIM(juDFT_string_for_argument("-diag"))=="elpa")       diag_solver=diag_elpa
       IF (TRIM(juDFT_string_for_argument("-diag"))=="elpa_1node") diag_solver=diag_elpa_1node
       IF (TRIM(juDFT_string_for_argument("-diag"))=="scalapack")  diag_solver=diag_scalapack
       IF (TRIM(juDFT_string_for_argument("-diag"))=="elemental")  diag_solver=diag_elemental
       IF (TRIM(juDFT_string_for_argument("-diag"))=="lapack")     diag_solver=diag_lapack
       IF (TRIM(juDFT_string_for_argument("-diag"))=="magma")      diag_solver=diag_magma
       IF (TRIM(juDFT_string_for_argument("-diag"))=="chase")      diag_solver=diag_chase
       IF (TRIM(juDFT_string_for_argument("-diag"))=="cusolver")   diag_solver=diag_cusolver
       IF (TRIM(juDFT_string_for_argument("-diag"))=="debugout")   diag_solver=diag_debugout
       !Check if solver is possible
       IF (diag_solver<0)  CALL juDFT_error(&
            "You selected a solver for the eigenvalue problem that is not available",&
            hint="You most probably did not provide the appropriate libraries for compilation/linking")
       IF (diag_solver<100.AND.parallel) CALL judft_error(&
            "You selected an eigensolver that does not support distributed memory parallism",&
            hint="Try scalapack,elpa or another supported solver for parallel matrices")
       IF (diag_solver>100.AND.diag_solver<200.AND..NOT.parallel) CALL judft_error(&
            "You selected an eigensolver for matrices that are memory distributed",&
            hint="Try lapack, cusolver or another supported solver for non-distributed matrices")
    END IF

  END FUNCTION select_solver

END MODULE m_available_solvers