Commit a43ac6d6 authored by Andreas Marek's avatar Andreas Marek

Introduce public method eigenvalues

parent 692d8cd8
...@@ -128,8 +128,9 @@ the user application): ...@@ -128,8 +128,9 @@ the user application):
6. do the desired task with the *ELPA* library, which could be 6. do the desired task with the *ELPA* library, which could be
a) e%eigenvectors ! solve EV problem with solver as set by "set" method; returns eigenvalues AND eigenvectors a) e%eigenvectors ! solve EV problem with solver as set by "set" method; computes eigenvalues AND eigenvectors
! (replaces a) and b) from legacy API) ! (replaces a) and b) from legacy API)
b) e%eigenvalues ! solve EV problem with solver as set by "set" method; computes eigenvalues only
b) e%solve_tridi ! solve problem with tridiagonal matrix (replacement for c) from legacy API) b) e%solve_tridi ! solve problem with tridiagonal matrix (replacement for c) from legacy API)
c) e%choleksy ! do a cholesky decomposition (replaces d) from legacy API) c) e%choleksy ! do a cholesky decomposition (replaces d) from legacy API)
d) e%invert_tridiagonal ! invert triangular matrix (replaces e) from legacy API) d) e%invert_tridiagonal ! invert triangular matrix (replaces e) from legacy API)
......
...@@ -59,7 +59,6 @@ Using *ELPA* with the latest API is done in the following steps ...@@ -59,7 +59,6 @@ Using *ELPA* with the latest API is done in the following steps
of the ELPA library has been build with GPU support enables of the ELPA library has been build with GPU support enables
- "timings" can be either 0 or 1, switches time measurements off or on - "timings" can be either 0 or 1, switches time measurements off or on
- "debug" can be either 0 or 1, switches detailed debug messages off/on - "debug" can be either 0 or 1, switches detailed debug messages off/on
- "eigenvalues_only" can be either 0 or 1. In case of 1 only compute the eigenvalues
- call ELPA-type function solve or others - call ELPA-type function solve or others
...@@ -67,6 +66,8 @@ Using *ELPA* with the latest API is done in the following steps ...@@ -67,6 +66,8 @@ Using *ELPA* with the latest API is done in the following steps
- "eigenvectors" solves the eigenvalue problem for single/double real/complex valued matrices and - "eigenvectors" solves the eigenvalue problem for single/double real/complex valued matrices and
returns the eigenvalues AND eigenvectors returns the eigenvalues AND eigenvectors
- "eigenvalues" solves the eigenvalue problem for single/double real/complex valued matrices and
returns the eigenvalues
- "hermetian_multipy" computes C = A^T * B (real) or C = A^H * B (complex) for single/double - "hermetian_multipy" computes C = A^T * B (real) or C = A^H * B (complex) for single/double
real/complex matrices real/complex matrices
- "cholesky" does a cholesky factorization for a single/double real/complex matrix - "cholesky" does a cholesky factorization for a single/double real/complex matrix
......
...@@ -102,8 +102,6 @@ function elpa_solve_evp_& ...@@ -102,8 +102,6 @@ function elpa_solve_evp_&
logical :: useGPU logical :: useGPU
logical :: success logical :: success
logical :: solve_eigenvectors
logical :: do_useGPU logical :: do_useGPU
integer(kind=ik) :: numberOfGPUDevices integer(kind=ik) :: numberOfGPUDevices
...@@ -114,7 +112,6 @@ function elpa_solve_evp_& ...@@ -114,7 +112,6 @@ function elpa_solve_evp_&
character(200) :: errorMessage character(200) :: errorMessage
integer(kind=ik) :: na, nev, lda, ldq, nblk, matrixCols, & integer(kind=ik) :: na, nev, lda, ldq, nblk, matrixCols, &
mpi_comm_rows, mpi_comm_cols, mpi_comm_all mpi_comm_rows, mpi_comm_cols, mpi_comm_all
integer(kind=ik) :: eigenvalues_only
call obj%timer%start("elpa_solve_evp_& call obj%timer%start("elpa_solve_evp_&
&MATH_DATATYPE& &MATH_DATATYPE&
...@@ -124,9 +121,9 @@ function elpa_solve_evp_& ...@@ -124,9 +121,9 @@ function elpa_solve_evp_&
if (present(q)) then if (present(q)) then
solve_eigenvectors =.true. obj%eigenvalues_only = .false.
else else
solve_eigenvectors = .false. obj%eigenvalues_only = .true.
endif endif
na = obj%na na = obj%na
...@@ -206,7 +203,7 @@ function elpa_solve_evp_& ...@@ -206,7 +203,7 @@ function elpa_solve_evp_&
endif endif
! allocate a dummy q_intern, if eigenvectors should not be commputed and thus q is NOT present ! allocate a dummy q_intern, if eigenvectors should not be commputed and thus q is NOT present
if ((solve_eigenvectors)) then if (.not.(obj%eigenvalues_only)) then
q_actual => q(1:obj%local_nrows,1:obj%local_ncols) q_actual => q(1:obj%local_nrows,1:obj%local_ncols)
else else
allocate(q_dummy(obj%local_nrows,obj%local_ncols)) allocate(q_dummy(obj%local_nrows,obj%local_ncols))
...@@ -261,15 +258,14 @@ function elpa_solve_evp_& ...@@ -261,15 +258,14 @@ function elpa_solve_evp_&
call obj%timer%stop("solve") call obj%timer%stop("solve")
if (.not.(success)) return if (.not.(success)) return
call obj%get("eigenvalues_only",eigenvalues_only) if (obj%eigenvalues_only) then
if (eigenvalues_only .eq. 1) then
return return
endif endif
if ((solve_eigenvectors) ) then if (.not.(obj%eigenvalues_only) ) then
! q must be given thats why from here on we can use q and not q_actual ! q must be given thats why from here on we can use q and not q_actual
#if COMPLEXCASE == 1 #if COMPLEXCASE == 1
ql(1:l_rows,1:l_cols_nev) = q_real(1:l_rows,1:l_cols_nev) q(1:l_rows,1:l_cols_nev) = q_real(1:l_rows,1:l_cols_nev)
#endif #endif
call obj%timer%start("back") call obj%timer%start("back")
...@@ -279,7 +275,7 @@ function elpa_solve_evp_& ...@@ -279,7 +275,7 @@ function elpa_solve_evp_&
&PRECISION& &PRECISION&
& (obj, na, nev, a, lda, tau, q, ldq, nblk, matrixCols, mpi_comm_rows, mpi_comm_cols, do_useGPU) & (obj, na, nev, a, lda, tau, q, ldq, nblk, matrixCols, mpi_comm_rows, mpi_comm_cols, do_useGPU)
call obj%timer%stop("back") call obj%timer%stop("back")
endif ! .not.solve_eigenvectors endif ! .not.(obj%eigenvalues_only
#if COMPLEXCASE == 1 #if COMPLEXCASE == 1
deallocate(q_real, stat=istat, errmsg=errorMessage) deallocate(q_real, stat=istat, errmsg=errorMessage)
...@@ -303,7 +299,7 @@ function elpa_solve_evp_& ...@@ -303,7 +299,7 @@ function elpa_solve_evp_&
stop 1 stop 1
endif endif
if (.not.(solve_eigenvectors)) then if (obj%eigenvalues_only) then
deallocate(q_dummy, stat=istat, errmsg=errorMessage) deallocate(q_dummy, stat=istat, errmsg=errorMessage)
if (istat .ne. 0) then if (istat .ne. 0) then
print *,"solve_evp_& print *,"solve_evp_&
......
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
integer(kind=c_intptr_t) :: tmat_dev, q_dev, a_dev integer(kind=c_intptr_t) :: tmat_dev, q_dev, a_dev
integer(kind=c_int) :: i integer(kind=c_int) :: i
logical :: success, successCUDA, solve_eigenvectors logical :: success, successCUDA
logical :: wantDebug logical :: wantDebug
integer(kind=c_int) :: istat, gpu, debug, qr integer(kind=c_int) :: istat, gpu, debug, qr
character(200) :: errorMessage character(200) :: errorMessage
...@@ -112,7 +112,6 @@ ...@@ -112,7 +112,6 @@
&MATH_DATATYPE &MATH_DATATYPE
integer(kind=ik) :: na, nev, lda, ldq, nblk, matrixCols, & integer(kind=ik) :: na, nev, lda, ldq, nblk, matrixCols, &
mpi_comm_rows, mpi_comm_cols, mpi_comm_all mpi_comm_rows, mpi_comm_cols, mpi_comm_all
integer(kind=ik) :: eigenvalues_only
call obj%timer%start("elpa_solve_evp_& call obj%timer%start("elpa_solve_evp_&
&MATH_DATATYPE& &MATH_DATATYPE&
...@@ -121,9 +120,9 @@ ...@@ -121,9 +120,9 @@
&") &")
if (present(q)) then if (present(q)) then
solve_eigenvectors = .true. obj%eigenvalues_only = .false.
else else
solve_eigenvectors = .false. obj%eigenvalues_only = .true.
endif endif
na = obj%na na = obj%na
...@@ -264,7 +263,7 @@ ...@@ -264,7 +263,7 @@
call obj%timer%start("bandred") call obj%timer%start("bandred")
if (solve_eigenvectors) then if (.not. obj%eigenvalues_only) then
q_actual => q(1:obj%local_nrows,1:obj%local_ncols) q_actual => q(1:obj%local_nrows,1:obj%local_ncols)
else else
allocate(q_dummy(1:obj%local_nrows,1:obj%local_ncols)) allocate(q_dummy(1:obj%local_nrows,1:obj%local_ncols))
...@@ -392,12 +391,11 @@ ...@@ -392,12 +391,11 @@
stop 1 stop 1
endif endif
call obj%get("eigenvalues_only",eigenvalues_only) if (obj%eigenvalues_only) then
if (eigenvalues_only .eq. 1) then
return return
endif endif
if (solve_eigenvectors) then if (.not. obj%eigenvalues_only) then
#if COMPLEXCASE == 1 #if COMPLEXCASE == 1
! q must be given thats why from here on we can use q and not q_actual ! q must be given thats why from here on we can use q and not q_actual
...@@ -471,9 +469,9 @@ ...@@ -471,9 +469,9 @@
endif endif
endif endif
call obj%timer%stop("trans_ev_to_full") call obj%timer%stop("trans_ev_to_full")
endif ! solve_eigenvectors endif ! .not. obj%eigenvalue_only
if (.not.(solve_eigenvectors)) then if (obj%eigenvalues_only) then
deallocate(q_dummy, stat=istat, errmsg=errorMessage) deallocate(q_dummy, stat=istat, errmsg=errorMessage)
if (istat .ne. 0) then if (istat .ne. 0) then
print *,"solve_evp_& print *,"solve_evp_&
......
...@@ -77,6 +77,7 @@ module elpa_abstract_impl ...@@ -77,6 +77,7 @@ module elpa_abstract_impl
#endif #endif
type(c_ptr) :: index = C_NULL_PTR type(c_ptr) :: index = C_NULL_PTR
logical :: eigenvalues_only
contains contains
! set private fields in the index ! set private fields in the index
generic, public :: set_private => & generic, public :: set_private => &
......
...@@ -113,9 +113,10 @@ static int elpa_double_value_to_string(char *name, double value, const char **st ...@@ -113,9 +113,10 @@ static int elpa_double_value_to_string(char *name, double value, const char **st
BASE_ENTRY(option_name, option_description, 0, 0, 0), \ BASE_ENTRY(option_name, option_description, 0, 0, 0), \
} }
#define PRIVATE_INT_ENTRY(option_name, option_description) \ #define PRIVATE_INT_ENTRY(option_name, default) \
{ \ { \
BASE_ENTRY(option_name, option_description, 0, 0, 1), \ BASE_ENTRY(option_name, NULL, 0, 0, 1), \
.default_value = default, \
} }
static const elpa_index_int_entry_t int_entries[] = { static const elpa_index_int_entry_t int_entries[] = {
...@@ -145,7 +146,7 @@ static const elpa_index_int_entry_t int_entries[] = { ...@@ -145,7 +146,7 @@ static const elpa_index_int_entry_t int_entries[] = {
BOOL_ENTRY("timings", "Enable time measurement", 0), BOOL_ENTRY("timings", "Enable time measurement", 0),
BOOL_ENTRY("debug", "Emit verbose debugging messages", 0), BOOL_ENTRY("debug", "Emit verbose debugging messages", 0),
BOOL_ENTRY("print_flops", "Print FLOP rates on task 0", 0), BOOL_ENTRY("print_flops", "Print FLOP rates on task 0", 0),
BOOL_ENTRY("eigenvalues_only", "Only compute the eigenvalues and return", 0), PRIVATE_INT_ENTRY("eigenvalues_only", 0),
}; };
#define READONLY_DOUBLE_ENTRY(option_name, option_description) \ #define READONLY_DOUBLE_ENTRY(option_name, option_description) \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment