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