Commit c5d41b6c authored by Lorenz Huedepohl's avatar Lorenz Huedepohl
Browse files

Make procedures that are part of a generic public

This prevented compilation with Intel 2018 Beta and solves issue #54. It
turns out you can only override type-bound procedures that are
accessible in the module where you override them, thus they have to be
private. A "deferred, private" type bound procedure could only be
overriden from the same module (or a submodule thereof).

Many thanks to Igor Vorobtsov from Intel for clarifying this.
parent 1041b5cd
......@@ -72,8 +72,8 @@
#endif
logical, intent(in) :: wantDebug
logical :: success
integer(kind=iK) :: successInternal
logical :: success ! the return value
integer :: error
class(elpa_t), pointer :: obj
!call timer%start("elpa_solve_tridi_&
......@@ -108,20 +108,16 @@
call obj%set("debug",1)
endif
select type(obj)
class is (elpa_abstract_impl_t)
success = elpa_solve_tridi_&
&PRECISION&
&_impl(obj, d, e, q)
!call obj%solve_tridi(d(1:na), e(1:na), q(1:ldq,1:matrixCols), successInternal)
if (.not.(success)) then
print *, "Cannot run solve_tridi"
return
endif
end select
call elpa_deallocate(obj)
call obj%solve_tridiagonal(d, e, q(1:ldq,1:matrixCols), error)
if (error /= ELPA_OK) then
print *, "Cannot run solve_tridi"
success = .false.
return
else
success = .true.
endif
call elpa_deallocate(obj)
call elpa_uninit()
!call timer%stop("elpa_solve_tridi_&
......
......@@ -94,11 +94,11 @@ module elpa_abstract_impl
procedure, private :: elpa_get_private_integer
procedure, private :: elpa_get_private_double
procedure, private :: elpa_set_integer !< private methods to implement the setting of an integer/double key/value pair
procedure, private :: elpa_set_double
procedure, public :: elpa_set_integer !< private methods to implement the setting of an integer/double key/value pair
procedure, public :: elpa_set_double
procedure, private :: elpa_get_integer !< private methods to implement the querry of an integer/double key/value pair
procedure, private :: elpa_get_double
procedure, public :: elpa_get_integer !< private methods to implement the querry of an integer/double key/value pair
procedure, public :: elpa_get_double
end type
......
......@@ -132,46 +132,45 @@ module elpa_api
elpa_invert_trm_dc, &
elpa_invert_trm_fc
generic, private :: solve_tridi => & !< method to solve the eigenvalue problem for a tridiagonal
elpa_solve_tridi_d, & !< matrix
elpa_solve_tridi_f
!> \brief private methods of elpa_t type. NOT accessible for the user
! privates
procedure(elpa_set_integer_i), deferred, private :: elpa_set_integer
procedure(elpa_set_double_i), deferred, private :: elpa_set_double
procedure(elpa_get_integer_i), deferred, private :: elpa_get_integer
procedure(elpa_get_double_i), deferred, private :: elpa_get_double
procedure(elpa_eigenvectors_d_i), deferred, private :: elpa_eigenvectors_d
procedure(elpa_eigenvectors_f_i), deferred, private :: elpa_eigenvectors_f
procedure(elpa_eigenvectors_dc_i), deferred, private :: elpa_eigenvectors_dc
procedure(elpa_eigenvectors_fc_i), deferred, private :: elpa_eigenvectors_fc
procedure(elpa_eigenvalues_d_i), deferred, private :: elpa_eigenvalues_d
procedure(elpa_eigenvalues_f_i), deferred, private :: elpa_eigenvalues_f
procedure(elpa_eigenvalues_dc_i), deferred, private :: elpa_eigenvalues_dc
procedure(elpa_eigenvalues_fc_i), deferred, private :: elpa_eigenvalues_fc
procedure(elpa_hermitian_multiply_d_i), deferred, private :: elpa_hermitian_multiply_d
procedure(elpa_hermitian_multiply_f_i), deferred, private :: elpa_hermitian_multiply_f
procedure(elpa_hermitian_multiply_dc_i), deferred, private :: elpa_hermitian_multiply_dc
procedure(elpa_hermitian_multiply_fc_i), deferred, private :: elpa_hermitian_multiply_fc
procedure(elpa_cholesky_d_i), deferred, private :: elpa_cholesky_d
procedure(elpa_cholesky_f_i), deferred, private :: elpa_cholesky_f
procedure(elpa_cholesky_dc_i), deferred, private :: elpa_cholesky_dc
procedure(elpa_cholesky_fc_i), deferred, private :: elpa_cholesky_fc
procedure(elpa_invert_trm_d_i), deferred, private :: elpa_invert_trm_d
procedure(elpa_invert_trm_f_i), deferred, private :: elpa_invert_trm_f
procedure(elpa_invert_trm_dc_i), deferred, private :: elpa_invert_trm_dc
procedure(elpa_invert_trm_fc_i), deferred, private :: elpa_invert_trm_fc
procedure(elpa_solve_tridi_d_i), deferred, private :: elpa_solve_tridi_d
procedure(elpa_solve_tridi_f_i), deferred, private :: elpa_solve_tridi_f
generic, public :: solve_tridiagonal => & !< method to solve the eigenvalue problem for a tridiagonal
elpa_solve_tridiagonal_d, & !< matrix
elpa_solve_tridiagonal_f
!> \brief These method have to be public, in order to be overrideable in the extension types
procedure(elpa_set_integer_i), deferred, public :: elpa_set_integer
procedure(elpa_set_double_i), deferred, public :: elpa_set_double
procedure(elpa_get_integer_i), deferred, public :: elpa_get_integer
procedure(elpa_get_double_i), deferred, public :: elpa_get_double
procedure(elpa_eigenvectors_d_i), deferred, public :: elpa_eigenvectors_d
procedure(elpa_eigenvectors_f_i), deferred, public :: elpa_eigenvectors_f
procedure(elpa_eigenvectors_dc_i), deferred, public :: elpa_eigenvectors_dc
procedure(elpa_eigenvectors_fc_i), deferred, public :: elpa_eigenvectors_fc
procedure(elpa_eigenvalues_d_i), deferred, public :: elpa_eigenvalues_d
procedure(elpa_eigenvalues_f_i), deferred, public :: elpa_eigenvalues_f
procedure(elpa_eigenvalues_dc_i), deferred, public :: elpa_eigenvalues_dc
procedure(elpa_eigenvalues_fc_i), deferred, public :: elpa_eigenvalues_fc
procedure(elpa_hermitian_multiply_d_i), deferred, public :: elpa_hermitian_multiply_d
procedure(elpa_hermitian_multiply_f_i), deferred, public :: elpa_hermitian_multiply_f
procedure(elpa_hermitian_multiply_dc_i), deferred, public :: elpa_hermitian_multiply_dc
procedure(elpa_hermitian_multiply_fc_i), deferred, public :: elpa_hermitian_multiply_fc
procedure(elpa_cholesky_d_i), deferred, public :: elpa_cholesky_d
procedure(elpa_cholesky_f_i), deferred, public :: elpa_cholesky_f
procedure(elpa_cholesky_dc_i), deferred, public :: elpa_cholesky_dc
procedure(elpa_cholesky_fc_i), deferred, public :: elpa_cholesky_fc
procedure(elpa_invert_trm_d_i), deferred, public :: elpa_invert_trm_d
procedure(elpa_invert_trm_f_i), deferred, public :: elpa_invert_trm_f
procedure(elpa_invert_trm_dc_i), deferred, public :: elpa_invert_trm_dc
procedure(elpa_invert_trm_fc_i), deferred, public :: elpa_invert_trm_fc
procedure(elpa_solve_tridiagonal_d_i), deferred, public :: elpa_solve_tridiagonal_d
procedure(elpa_solve_tridiagonal_f_i), deferred, public :: elpa_solve_tridiagonal_f
end type elpa_t
......@@ -1079,7 +1078,7 @@ module elpa_api
!> \param q double real matrix: on output contains the eigenvectors
!> \param error integer, optional : error code, which can be queried with elpa_strerr
abstract interface
subroutine elpa_solve_tridi_d_i (self, d, e, q, error)
subroutine elpa_solve_tridiagonal_d_i (self, d, e, q, error)
use iso_c_binding
import elpa_t
implicit none
......@@ -1108,7 +1107,7 @@ module elpa_api
!> \param q single real matrix: on output contains the eigenvectors
!> \param error integer, optional : error code, which can be queried with elpa_strerr
abstract interface
subroutine elpa_solve_tridi_f_i (self, d, e, q, error)
subroutine elpa_solve_tridiagonal_f_i (self, d, e, q, error)
use iso_c_binding
import elpa_t
implicit none
......
......@@ -81,46 +81,49 @@ module elpa_impl
procedure, public :: timer_stop => elpa_timer_stop
!> \brief the private methods
procedure, private :: elpa_eigenvectors_d !< private methods to implement the solve step for real/complex
!< double/single matrices
procedure, private :: elpa_eigenvectors_f
procedure, private :: elpa_eigenvectors_dc
procedure, private :: elpa_eigenvectors_fc
procedure, private :: elpa_eigenvalues_d !< private methods to implement the solve step for real/complex
!< double/single matrices; only the eigenvalues are computed
procedure, private :: elpa_eigenvalues_f
procedure, private :: elpa_eigenvalues_dc
procedure, private :: elpa_eigenvalues_fc
procedure, private :: elpa_hermitian_multiply_d !< private methods to implement a "hermitian" multiplication of matrices a and b
procedure, private :: elpa_hermitian_multiply_f !< for real valued matrices: a**T * b
procedure, private :: elpa_hermitian_multiply_dc !< for complex valued matrices: a**H * b
procedure, private :: elpa_hermitian_multiply_fc
procedure, private :: elpa_cholesky_d !< private methods to implement the cholesky factorisation of
!< real/complex double/single matrices
procedure, private :: elpa_cholesky_f
procedure, private :: elpa_cholesky_dc
procedure, private :: elpa_cholesky_fc
procedure, private :: elpa_invert_trm_d !< private methods to implement the inversion of a triangular
!< real/complex double/single matrix
procedure, private :: elpa_invert_trm_f
procedure, private :: elpa_invert_trm_dc
procedure, private :: elpa_invert_trm_fc
procedure, private :: elpa_solve_tridi_d !< private methods to implement the solve step for a real valued
procedure, private :: elpa_solve_tridi_f !< double/single tridiagonal matrix
procedure, private :: associate_int => elpa_associate_int !< private method to set some pointers
!> \brief the implemenation methods
procedure, public :: elpa_eigenvectors_d !< public methods to implement the solve step for real/complex
!< double/single matrices
procedure, public :: elpa_eigenvectors_f
procedure, public :: elpa_eigenvectors_dc
procedure, public :: elpa_eigenvectors_fc
procedure, public :: elpa_eigenvalues_d !< public methods to implement the solve step for real/complex
!< double/single matrices; only the eigenvalues are computed
procedure, public :: elpa_eigenvalues_f
procedure, public :: elpa_eigenvalues_dc
procedure, public :: elpa_eigenvalues_fc
procedure, public :: elpa_hermitian_multiply_d !< public methods to implement a "hermitian" multiplication of matrices a and b
procedure, public :: elpa_hermitian_multiply_f !< for real valued matrices: a**T * b
procedure, public :: elpa_hermitian_multiply_dc !< for complex valued matrices: a**H * b
procedure, public :: elpa_hermitian_multiply_fc
procedure, public :: elpa_cholesky_d !< public methods to implement the cholesky factorisation of
!< real/complex double/single matrices
procedure, public :: elpa_cholesky_f
procedure, public :: elpa_cholesky_dc
procedure, public :: elpa_cholesky_fc
procedure, public :: elpa_invert_trm_d !< public methods to implement the inversion of a triangular
!< real/complex double/single matrix
procedure, public :: elpa_invert_trm_f
procedure, public :: elpa_invert_trm_dc
procedure, public :: elpa_invert_trm_fc
procedure, public :: elpa_solve_tridiagonal_d !< public methods to implement the solve step for a real valued
procedure, public :: elpa_solve_tridiagonal_f !< double/single tridiagonal matrix
procedure, public :: associate_int => elpa_associate_int !< public method to set some pointers
end type elpa_impl_t
!> \brief the implementation of the private methods
!> \brief the implementation of the generic methods
contains
!> \brief function to allocate an ELPA object
!> Parameters
!> \param error integer, optional to get an error code
......@@ -1873,7 +1876,7 @@ module elpa_impl
end subroutine
!> \brief elpa_solve_tridi_d: class method to solve the eigenvalue problem for a double real tridiagonal matrix a
!> \brief elpa_solve_tridiagonal_d: class method to solve the eigenvalue problem for a double real tridiagonal matrix a
!>
!> The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
!> block size, and the MPI communicators are already known to the object and MUST be set BEFORE
......@@ -1890,7 +1893,7 @@ module elpa_impl
!> \param q matrix on exit : contains the eigenvectors
!> \param error integer, optional: returns an error code, which can be queried with elpa_strerr
!> \todo e should have dimension (na - 1)
subroutine elpa_solve_tridi_d (self, d, e, q, error)
subroutine elpa_solve_tridiagonal_d (self, d, e, q, error)
use iso_c_binding
use elpa1_auxiliary_impl
use precision
......@@ -1913,12 +1916,12 @@ module elpa_impl
error = ELPA_ERROR
endif
else if (.not. success_l) then
write(error_unit,'(a)') "ELPA: Error in solve_tridi() and you did not check for errors!"
write(error_unit,'(a)') "ELPA: Error in solve_tridiagonal() and you did not check for errors!"
endif
end subroutine
!> \brief elpa_solve_tridi_f: class method to solve the eigenvalue problem for a float real tridiagonal matrix a
!> \brief elpa_solve_tridiagonal_f: class method to solve the eigenvalue problem for a float real tridiagonal matrix a
!>
!> The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
!> block size, and the MPI communicators are already known to the object and MUST be set BEFORE
......@@ -1935,7 +1938,7 @@ module elpa_impl
!> \param q matrix on exit : contains the eigenvectors
!> \param error integer, optional: returns an error code, which can be queried with elpa_strerr
!> \todo e should have dimension (na - 1)
subroutine elpa_solve_tridi_f (self, d, e, q, error)
subroutine elpa_solve_tridiagonal_f (self, d, e, q, error)
use iso_c_binding
use elpa1_auxiliary_impl
use precision
......@@ -1959,7 +1962,7 @@ module elpa_impl
error = ELPA_ERROR
endif
else if (.not. success_l) then
write(error_unit,'(a)') "ELPA: Error in solve_tridi() and you did not check for errors!"
write(error_unit,'(a)') "ELPA: Error in solve_tridiagonal() and you did not check for errors!"
endif
#else
print *,"This installation of the ELPA library has not been build with single-precision support"
......
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