LCOV - code coverage report
Current view: top level - src - elpa_api.F90 (source / functions) Hit Total Coverage
Test: coverage_50ab7a7628bba174fc62cee3ab72b26e81f87fe5.info Lines: 28 48 58.3 %
Date: 2018-01-10 09:29:53 Functions: 7 10 70.0 %

          Line data    Source code
       1             : !
       2             : !    Copyright 2017, L. Hüdepohl and A. Marek, MPCDF
       3             : !
       4             : !    This file is part of ELPA.
       5             : !
       6             : !    The ELPA library was originally created by the ELPA consortium,
       7             : !    consisting of the following organizations:
       8             : !
       9             : !    - Max Planck Computing and Data Facility (MPCDF), formerly known as
      10             : !      Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
      11             : !    - Bergische Universität Wuppertal, Lehrstuhl für angewandte
      12             : !      Informatik,
      13             : !    - Technische Universität München, Lehrstuhl für Informatik mit
      14             : !      Schwerpunkt Wissenschaftliches Rechnen ,
      15             : !    - Fritz-Haber-Institut, Berlin, Abt. Theorie,
      16             : !    - Max-Plack-Institut für Mathematik in den Naturwissenschaften,
      17             : !      Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
      18             : !      and
      19             : !    - IBM Deutschland GmbH
      20             : !
      21             : !    This particular source code file contains additions, changes and
      22             : !    enhancements authored by Intel Corporation which is not part of
      23             : !    the ELPA consortium.
      24             : !
      25             : !    More information can be found here:
      26             : !    http://elpa.mpcdf.mpg.de/
      27             : !
      28             : !    ELPA is free software: you can redistribute it and/or modify
      29             : !    it under the terms of the version 3 of the license of the
      30             : !    GNU Lesser General Public License as published by the Free
      31             : !    Software Foundation.
      32             : !
      33             : !    ELPA is distributed in the hope that it will be useful,
      34             : !    but WITHOUT ANY WARRANTY; without even the implied warranty of
      35             : !    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      36             : !    GNU Lesser General Public License for more details.
      37             : !
      38             : !    You should have received a copy of the GNU Lesser General Public License
      39             : !    along with ELPA.  If not, see <http://www.gnu.org/licenses/>
      40             : !
      41             : !    ELPA reflects a substantial effort on the part of the original
      42             : !    ELPA consortium, and we ask you to respect the spirit of the
      43             : !    license that we chose: i.e., please contribute any changes you
      44             : !    may have back to the original ELPA library distribution, and keep
      45             : !    any derivatives of ELPA under the same license that we chose for
      46             : !    the original distribution, the GNU Lesser General Public License.
      47             : !
      48             : !> \brief Fortran module which provides the definition of the ELPA API. Do not use directly! Use the module "elpa"
      49             : 
      50             : #include "config-f90.h"
      51             : 
      52             : module elpa_api
      53             :   use elpa_constants
      54             :   use, intrinsic :: iso_c_binding
      55             :   implicit none
      56             : 
      57             : #include "src/elpa_generated_public_fortran_interfaces.h"
      58             : 
      59             :   integer, private, parameter :: earliest_api_version = EARLIEST_API_VERSION !< Definition of the earliest API version supported
      60             :                                                                              !< with the current release
      61             :   integer, private, parameter :: current_api_version  = CURRENT_API_VERSION  !< Definition of the current API version
      62             : 
      63             :   integer, private, parameter :: earliest_autotune_version = EARLIEST_AUTOTUNE_VERSION !< Definition of the earliest API version
      64             :                                                                                        !< which supports autotuning
      65             :   integer, private            :: api_version_set
      66             :   logical, private            :: initDone = .false.
      67             : 
      68             :   public :: elpa_t, &
      69             :       c_int, &
      70             :       c_double, c_double_complex, &
      71             :       c_float, c_float_complex
      72             : 
      73             :   !> \brief Abstract definition of the elpa_t type
      74             :   type, abstract :: elpa_t
      75             :     private
      76             : 
      77             : 
      78             :     !< these have to be public for proper bounds checking, sadly
      79             :     integer(kind=c_int), public, pointer :: na => NULL()
      80             :     integer(kind=c_int), public, pointer :: nev => NULL()
      81             :     integer(kind=c_int), public, pointer :: local_nrows => NULL()
      82             :     integer(kind=c_int), public, pointer :: local_ncols => NULL()
      83             :     integer(kind=c_int), public, pointer :: nblk => NULL()
      84             : 
      85             :     contains
      86             :       ! general
      87             :       procedure(elpa_setup_i),   deferred, public :: setup          !< method to setup an ELPA object
      88             :       procedure(elpa_destroy_i), deferred, public :: destroy        !< method to destroy an ELPA object
      89             : 
      90             :       ! key/value store
      91             :       generic, public :: set => &                                   !< export a method to set integer/double key/values
      92             :           elpa_set_integer, &
      93             :           elpa_set_double
      94             : 
      95             :       generic, public :: get => &                                   !< export a method to get integer/double key/values
      96             :           elpa_get_integer, &
      97             :           elpa_get_double
      98             : 
      99             :       procedure(elpa_is_set_i),  deferred, public :: is_set         !< method to check whether key/value is set
     100             :       procedure(elpa_can_set_i), deferred, public :: can_set        !< method to check whether key/value can be set
     101             : 
     102             :       ! Timer
     103             :       procedure(elpa_get_time_i), deferred, public :: get_time        !< method to get the times from the timer object
     104             :       procedure(elpa_print_times_i), deferred, public :: print_times  !< method to print the timings tree
     105             :       procedure(elpa_timer_start_i), deferred, public :: timer_start  !< method to start a time measurement
     106             :       procedure(elpa_timer_stop_i), deferred, public :: timer_stop    !< method to stop a time measurement
     107             : 
     108             : 
     109             :       ! Actual math routines
     110             :       generic, public :: eigenvectors => &                          !< method eigenvectors for solving the full eigenvalue problem
     111             :           elpa_eigenvectors_d, &                                    !< the eigenvalues and (parts of) the eigenvectors are computed
     112             :           elpa_eigenvectors_f, &                                    !< for symmetric real valued / hermitian complex valued matrices
     113             :           elpa_eigenvectors_dc, &
     114             :           elpa_eigenvectors_fc
     115             : 
     116             :       generic, public :: eigenvalues => &                           !< method eigenvalues for solving the eigenvalue problem
     117             :           elpa_eigenvalues_d, &                                     !< only the eigenvalues are computed
     118             :           elpa_eigenvalues_f, &                                     !< for symmetric real valued / hermitian complex valued matrices
     119             :           elpa_eigenvalues_dc, &
     120             :           elpa_eigenvalues_fc
     121             : 
     122             : #if 0
     123             :       generic, public :: generalized_eigenvectors => &              !< method eigenvectors for solving the full generalized eigenvalue problem
     124             :           elpa_generalized_eigenvectors_d, &                        !< the eigenvalues and (parts of) the eigenvectors are computed
     125             :           elpa_generalized_eigenvectors_f, &                        !< for symmetric real valued / hermitian complex valued matrices
     126             :           elpa_generalized_eigenvectors_dc, &
     127             :           elpa_generalized_eigenvectors_fc
     128             : #endif
     129             : 
     130             :       generic, public :: hermitian_multiply => &                    !< method for a "hermitian" multiplication of matrices a and b
     131             :           elpa_hermitian_multiply_d, &                              !< for real valued matrices:   a**T * b
     132             :           elpa_hermitian_multiply_dc, &                             !< for complex valued matrices a**H * b
     133             :           elpa_hermitian_multiply_f, &
     134             :           elpa_hermitian_multiply_fc
     135             : 
     136             :       generic, public :: cholesky => &                              !< method for the cholesky factorisation of matrix a
     137             :           elpa_cholesky_d, &
     138             :           elpa_cholesky_f, &
     139             :           elpa_cholesky_dc, &
     140             :           elpa_cholesky_fc
     141             : 
     142             :       generic, public :: invert_triangular => &                     !< method to invert a upper triangular matrix a
     143             :           elpa_invert_trm_d, &
     144             :           elpa_invert_trm_f, &
     145             :           elpa_invert_trm_dc, &
     146             :           elpa_invert_trm_fc
     147             : 
     148             :       generic, public :: solve_tridiagonal => &                      !< method to solve the eigenvalue problem for a tridiagonal
     149             :           elpa_solve_tridiagonal_d, &                                !< matrix
     150             :           elpa_solve_tridiagonal_f
     151             : 
     152             :       ! Auto-tune
     153             :       procedure(elpa_autotune_setup_i), deferred, public :: autotune_setup       !< method to prepare the ELPA autotuning
     154             :       procedure(elpa_autotune_step_i), deferred, public :: autotune_step         !< method to do an autotuning step
     155             :       procedure(elpa_autotune_set_best_i), deferred, public :: autotune_set_best !< method to set the best options
     156             : 
     157             :       !> \brief These method have to be public, in order to be overrideable in the extension types
     158             :       procedure(elpa_set_integer_i), deferred, public :: elpa_set_integer
     159             :       procedure(elpa_set_double_i),  deferred, public :: elpa_set_double
     160             : 
     161             :       procedure(elpa_get_integer_i), deferred, public :: elpa_get_integer
     162             :       procedure(elpa_get_double_i),  deferred, public :: elpa_get_double
     163             : 
     164             :       procedure(elpa_eigenvectors_d_i),    deferred, public :: elpa_eigenvectors_d
     165             :       procedure(elpa_eigenvectors_f_i),    deferred, public :: elpa_eigenvectors_f
     166             :       procedure(elpa_eigenvectors_dc_i), deferred, public :: elpa_eigenvectors_dc
     167             :       procedure(elpa_eigenvectors_fc_i), deferred, public :: elpa_eigenvectors_fc
     168             : 
     169             :       procedure(elpa_eigenvalues_d_i),    deferred, public :: elpa_eigenvalues_d
     170             :       procedure(elpa_eigenvalues_f_i),    deferred, public :: elpa_eigenvalues_f
     171             :       procedure(elpa_eigenvalues_dc_i), deferred, public :: elpa_eigenvalues_dc
     172             :       procedure(elpa_eigenvalues_fc_i), deferred, public :: elpa_eigenvalues_fc
     173             : 
     174             : #if 0
     175             :       procedure(elpa_generalized_eigenvectors_d_i),    deferred, public :: elpa_generalized_eigenvectors_d
     176             :       procedure(elpa_generalized_eigenvectors_f_i),    deferred, public :: elpa_generalized_eigenvectors_f
     177             :       procedure(elpa_generalized_eigenvectors_dc_i), deferred, public :: elpa_generalized_eigenvectors_dc
     178             :       procedure(elpa_generalized_eigenvectors_fc_i), deferred, public :: elpa_generalized_eigenvectors_fc
     179             : #endif
     180             : 
     181             :       procedure(elpa_hermitian_multiply_d_i),  deferred, public :: elpa_hermitian_multiply_d
     182             :       procedure(elpa_hermitian_multiply_f_i),  deferred, public :: elpa_hermitian_multiply_f
     183             :       procedure(elpa_hermitian_multiply_dc_i), deferred, public :: elpa_hermitian_multiply_dc
     184             :       procedure(elpa_hermitian_multiply_fc_i), deferred, public :: elpa_hermitian_multiply_fc
     185             : 
     186             :       procedure(elpa_cholesky_d_i),    deferred, public :: elpa_cholesky_d
     187             :       procedure(elpa_cholesky_f_i),    deferred, public :: elpa_cholesky_f
     188             :       procedure(elpa_cholesky_dc_i), deferred, public :: elpa_cholesky_dc
     189             :       procedure(elpa_cholesky_fc_i), deferred, public :: elpa_cholesky_fc
     190             : 
     191             :       procedure(elpa_invert_trm_d_i),    deferred, public :: elpa_invert_trm_d
     192             :       procedure(elpa_invert_trm_f_i),    deferred, public :: elpa_invert_trm_f
     193             :       procedure(elpa_invert_trm_dc_i), deferred, public :: elpa_invert_trm_dc
     194             :       procedure(elpa_invert_trm_fc_i), deferred, public :: elpa_invert_trm_fc
     195             : 
     196             :       procedure(elpa_solve_tridiagonal_d_i), deferred, public :: elpa_solve_tridiagonal_d
     197             :       procedure(elpa_solve_tridiagonal_f_i), deferred, public :: elpa_solve_tridiagonal_f
     198             :   end type elpa_t
     199             : 
     200             : 
     201             :   !> \brief Abstract definition of the elpa_autotune type
     202             :   type, abstract :: elpa_autotune_t
     203             :     private
     204             :     contains
     205             :       procedure(elpa_autotune_destroy_i), deferred, public :: destroy
     206             :       procedure(elpa_autotune_print_i), deferred, public :: print
     207             :   end type
     208             : 
     209             : 
     210             :   !> \brief definition of helper function to get C strlen
     211             :   !> Parameters
     212             :   !> \details
     213             :   !> \param   ptr         type(c_ptr) : pointer to string
     214             :   !> \result  size        integer(kind=c_size_t) : length of string
     215             :   interface
     216             :     pure function elpa_strlen_c(ptr) result(size) bind(c, name="strlen")
     217             :       use, intrinsic :: iso_c_binding
     218             :       implicit none
     219             :       type(c_ptr), intent(in), value :: ptr
     220             :       integer(kind=c_size_t) :: size
     221             :     end function
     222             :   end interface
     223             : 
     224             : 
     225             :   !> \brief abstract definition of the ELPA setup method
     226             :   !> Parameters
     227             :   !> \details
     228             :   !> \param   self        class(elpa_t): the ELPA object
     229             :   !> \result  error       integer : error code, which can be queried with elpa_strerr()
     230             :   abstract interface
     231             :     function elpa_setup_i(self) result(error)
     232             :       import elpa_t
     233             :       implicit none
     234             :       class(elpa_t), intent(inout) :: self
     235             :       integer :: error
     236             :     end function
     237             :   end interface
     238             : 
     239             : 
     240             :   !> \brief abstract definition of the autotune setup method
     241             :   !> Parameters
     242             :   !> \details
     243             :   !> \param   self        class(elpa_t): the ELPA object, which should be tuned
     244             :   !> \param   level       integer: the level of "thoroughness" of the tuning steps
     245             :   !> \param   domain      integer: domain (real/complex) which should be tuned
     246             :   !> \result  tune_state  class(elpa_autotune_t): the autotuning object
     247             :   abstract interface
     248             :     function elpa_autotune_setup_i(self, level, domain, error) result(tune_state)
     249             :       import elpa_t, elpa_autotune_t
     250             :       implicit none
     251             :       class(elpa_t), intent(inout), target :: self
     252             :       integer, intent(in)                  :: level, domain
     253             :       class(elpa_autotune_t), pointer      :: tune_state
     254             : #ifdef USE_FORTRAN2008
     255             :       integer , optional                   :: error
     256             : #else
     257             :       integer                              :: error
     258             : #endif
     259             :     end function
     260             :   end interface
     261             : 
     262             : 
     263             :   !> \brief abstract definition of the autotune step method
     264             :   !> Parameters
     265             :   !> \details
     266             :   !> \param   self        class(elpa_t): the ELPA object, which should be tuned
     267             :   !> \param   tune_state  class(elpa_autotune_t): the autotuning object
     268             :   !> \param   unfinished  logical: state whether tuning is unfinished or not
     269             :   abstract interface
     270             :     function elpa_autotune_step_i(self, tune_state) result(unfinished)
     271             :       import elpa_t, elpa_autotune_t
     272             :       implicit none
     273             :       class(elpa_t), intent(inout) :: self
     274             :       class(elpa_autotune_t), intent(inout), target :: tune_state
     275             :       logical :: unfinished
     276             :     end function
     277             :   end interface
     278             : 
     279             :   
     280             :   !> \brief abstract definition of the autotune set_best method
     281             :   !> Parameters
     282             :   !> \details
     283             :   !> \param   self        class(elpa_t): the ELPA object, which should be tuned
     284             :   !> \param   tune_state  class(elpa_autotune_t): the autotuning object
     285             :   !> Sets the best combination of ELPA options
     286             :   abstract interface
     287             :     subroutine elpa_autotune_set_best_i(self, tune_state)
     288             :       import elpa_t, elpa_autotune_t
     289             :       implicit none
     290             :       class(elpa_t), intent(inout) :: self
     291             :       class(elpa_autotune_t), intent(in), target :: tune_state
     292             :     end subroutine
     293             :   end interface
     294             : 
     295             : 
     296             :   !> \brief abstract definition of set method for integer values
     297             :   !> Parameters
     298             :   !> \details
     299             :   !> \param   self        class(elpa_t): the ELPA object
     300             :   !> \param   name        string: the name of the key
     301             :   !> \param   value       integer : the value to set for the key
     302             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr()
     303             :   abstract interface
     304             :     subroutine elpa_set_integer_i(self, name, value, error)
     305             :       use iso_c_binding
     306             :       import elpa_t
     307             :       implicit none
     308             :       class(elpa_t)                   :: self
     309             :       character(*), intent(in)        :: name
     310             :       integer(kind=c_int), intent(in) :: value
     311             : #ifdef USE_FORTRAN2008
     312             :       integer, optional               :: error
     313             : #else
     314             :       integer                         :: error
     315             : #endif
     316             :     end subroutine
     317             :   end interface
     318             : 
     319             : 
     320             :   !> \brief abstract definition of get method for integer values
     321             :   !> Parameters
     322             :   !> \details
     323             :   !> \param   self        class(elpa_t): the ELPA object
     324             :   !> \param   name        string: the name of the key
     325             :   !> \param   value       integer : the value corresponding to the key
     326             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr()
     327             :   abstract interface
     328             :     subroutine elpa_get_integer_i(self, name, value, error)
     329             :       use iso_c_binding
     330             :       import elpa_t
     331             :       implicit none
     332             :       class(elpa_t)                  :: self
     333             :       character(*), intent(in)       :: name
     334             :       integer(kind=c_int)            :: value
     335             : #ifdef USE_FORTRAN2008
     336             :       integer, intent(out), optional :: error
     337             : #else
     338             :       integer, intent(out)           :: error
     339             : #endif
     340             :     end subroutine
     341             :   end interface
     342             : 
     343             : 
     344             :   !> \brief abstract definition of is_set method for integer values
     345             :   !> Parameters
     346             :   !> \details
     347             :   !> \param   self        class(elpa_t): the ELPA object
     348             :   !> \param   name        string: the name of the key
     349             :   !> \result  state       integer : 1 is set, 0 if not, else a negativ error code
     350             :   !>                                                    which can be queried with elpa_strerr
     351             :   abstract interface
     352             :     function elpa_is_set_i(self, name) result(state)
     353             :       import elpa_t
     354             :       implicit none
     355             :       class(elpa_t)            :: self
     356             :       character(*), intent(in) :: name
     357             :       integer                  :: state
     358             :     end function
     359             :   end interface
     360             : 
     361             : 
     362             :   !> \brief abstract definition of can_set method for integer values
     363             :   !> Parameters
     364             :   !> \details
     365             :   !> \param   self        class(elpa_t): the ELPA object
     366             :   !> \param   name        string: the name of the key
     367             :   !> \param   value       integer: the valye to associate with the key
     368             :   !> \result  state       integer : 1 is set, 0 if not, else a negativ error code
     369             :   !>                                                    which can be queried with elpa_strerr
     370             :   abstract interface
     371             :     function elpa_can_set_i(self, name, value) result(state)
     372             :       import elpa_t, c_int
     373             :       implicit none
     374             :       class(elpa_t)                   :: self
     375             :       character(*), intent(in)        :: name
     376             :       integer(kind=c_int), intent(in) :: value
     377             :       integer                         :: state
     378             :     end function
     379             :   end interface
     380             : 
     381             : 
     382             :   !> \brief abstract definition of set method for double values
     383             :   !> Parameters
     384             :   !> \details
     385             :   !> \param   self        class(elpa_t): the ELPA object
     386             :   !> \param   name        string: the name of the key
     387             :   !? \param   value       double: the value to associate with the key
     388             :   !> \param   error       integer. optional : error code, which can be queried with elpa_strerr
     389             :   abstract interface
     390             :     subroutine elpa_set_double_i(self, name, value, error)
     391             :       use iso_c_binding
     392             :       import elpa_t
     393             :       implicit none
     394             :       class(elpa_t)                   :: self
     395             :       character(*), intent(in)        :: name
     396             :       real(kind=c_double), intent(in) :: value
     397             : #ifdef USE_FORTRAN2008
     398             :       integer, optional               :: error
     399             : #else
     400             :       integer                         :: error
     401             : #endif
     402             :     end subroutine
     403             :   end interface
     404             : 
     405             : 
     406             :   !> \brief abstract definition of get method for double values
     407             :   !> Parameters
     408             :   !> \details
     409             :   !> \param   self        class(elpa_t): the ELPA object
     410             :   !> \param   name        string: the name of the key
     411             :   !> \param   value       double: the value associated with the key
     412             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
     413             :   abstract interface
     414             :     subroutine elpa_get_double_i(self, name, value, error)
     415             :       use iso_c_binding
     416             :       import elpa_t
     417             :       implicit none
     418             :       class(elpa_t)                  :: self
     419             :       character(*), intent(in)       :: name
     420             :       real(kind=c_double)            :: value
     421             : #ifdef USE_FORTRAN2008
     422             :       integer, intent(out), optional :: error
     423             : #else
     424             :       integer, intent(out)           :: error
     425             : #endif
     426             :     end subroutine
     427             :   end interface
     428             : 
     429             : 
     430             :   !> \brief abstract definition of associate method for integer pointers
     431             :   !> Parameters
     432             :   !> \details
     433             :   !> \param   self        class(elpa_t): the ELPA object
     434             :   !> \param   name        string: the name of the key
     435             :   !> \result  value       integer, pointer: the value associated with the key
     436             :   abstract interface
     437             :     function elpa_associate_int_i(self, name) result(value)
     438             :       use iso_c_binding
     439             :       import elpa_t
     440             :       implicit none
     441             :       class(elpa_t)                  :: self
     442             :       character(*), intent(in)       :: name
     443             :       integer(kind=c_int), pointer   :: value
     444             :     end function
     445             :   end interface
     446             : 
     447             : 
     448             :   ! Timer routines
     449             : 
     450             :   !> \brief abstract definition of get_time method to querry the timer
     451             :   !> Parameters
     452             :   !> \details
     453             :   !> \param   self        class(elpa_t): the ELPA object
     454             :   !> \param   name1..6    string: the name of the timer entry, supports up to 6 levels
     455             :   !> \result  s           double: the time for the entry name1..6
     456             :   abstract interface
     457             :     function elpa_get_time_i(self, name1, name2, name3, name4, name5, name6) result(s)
     458             :       import elpa_t, c_double
     459             :       implicit none
     460             :       class(elpa_t), intent(in) :: self
     461             :       ! this is clunky, but what can you do..
     462             :       character(len=*), intent(in), optional :: name1, name2, name3, name4, name5, name6
     463             :       real(kind=c_double) :: s
     464             :     end function
     465             :   end interface
     466             : 
     467             : 
     468             :   !> \brief abstract definition of print method for timer
     469             :   !> Parameters
     470             :   !> \details
     471             :   !> \param   self        class(elpa_t): the ELPA object
     472             :   abstract interface
     473             :     subroutine elpa_print_times_i(self, name1, name2, name3, name4)
     474             :       import elpa_t
     475             :       implicit none
     476             :       class(elpa_t), intent(in) :: self
     477             :       character(len=*), intent(in), optional :: name1, name2, name3, name4
     478             :     end subroutine
     479             :   end interface
     480             : 
     481             : 
     482             :   !> \brief abstract definition of the start method for timer
     483             :   !> Parameters
     484             :   !> \details
     485             :   !> \param   self        class(elpa_t): the ELPA object
     486             :   !> \param   name        character(len=*) the name of the entry int the timer tree
     487             :   abstract interface
     488             :     subroutine elpa_timer_start_i(self, name)
     489             :       import elpa_t
     490             :       implicit none
     491             :       class(elpa_t), intent(inout) :: self
     492             :       character(len=*), intent(in) :: name
     493             :     end subroutine
     494             :   end interface
     495             : 
     496             : 
     497             :   !> \brief abstract definition of the stop method for timer
     498             :   !> Parameters
     499             :   !> \details
     500             :   !> \param   self        class(elpa_t): the ELPA object
     501             :   !> \param   name        character(len=*) the name of the entry int the timer tree
     502             :   abstract interface
     503             :     subroutine elpa_timer_stop_i(self, name)
     504             :       import elpa_t
     505             :       implicit none
     506             :       class(elpa_t), intent(inout) :: self
     507             :       character(len=*), intent(in) :: name
     508             :     end subroutine
     509             :   end interface
     510             : 
     511             :   ! Actual math routines
     512             : 
     513             :   !> \brief abstract definition of interface to solve double real eigenvalue problem
     514             :   !>
     515             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
     516             :   !>  blocksize, the number of eigenvectors
     517             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     518             :   !>  with the class method "setup"
     519             :   !>
     520             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     521             :   !>  class method "set"
     522             :   !> Parameters
     523             :   !> \details
     524             :   !> \param   self        class(elpa_t), the ELPA object
     525             :   !> \param   a           double real matrix a: defines the problem to solve
     526             :   !> \param   ev          double real: on output stores the eigenvalues
     527             :   !> \param   q           double real matrix q: on output stores the eigenvalues
     528             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     529             :   abstract interface
     530             :     subroutine elpa_eigenvectors_d_i(self, a, ev, q, error)
     531             :       use iso_c_binding
     532             :       import elpa_t
     533             :       implicit none
     534             :       class(elpa_t)       :: self
     535             : #ifdef USE_ASSUMED_SIZE
     536             :       real(kind=c_double) :: a(self%local_nrows, *), q(self%local_nrows,*)
     537             : #else
     538             :       real(kind=c_double) :: a(self%local_nrows, self%local_ncols), q(self%local_nrows, self%local_ncols)
     539             : #endif
     540             :       real(kind=c_double) :: ev(self%na)
     541             : 
     542             : #ifdef USE_FORTRAN2008
     543             :       integer, optional   :: error
     544             : #else
     545             :       integer             :: error
     546             : #endif
     547             :     end subroutine
     548             :   end interface
     549             : 
     550             : 
     551             :   !> \brief abstract definition of interface to solve single real eigenvalue problem
     552             :   !>
     553             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
     554             :   !>  blocksize, the number of eigenvectors
     555             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     556             :   !>  with the class method "setup"
     557             :   !>
     558             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     559             :   !>  class method "set"
     560             :   !> Parameters
     561             :   !> \details
     562             :   !> \param   self        class(elpa_t), the ELPA object
     563             :   !> \param   a           single real matrix a: defines the problem to solve
     564             :   !> \param   ev          single real: on output stores the eigenvalues
     565             :   !> \param   q           single real matrix q: on output stores the eigenvalues
     566             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     567             :   abstract interface
     568             :     subroutine elpa_eigenvectors_f_i(self, a, ev, q, error)
     569             :       use iso_c_binding
     570             :       import elpa_t
     571             :       implicit none
     572             :       class(elpa_t)       :: self
     573             : #ifdef USE_ASSUMED_SIZE
     574             :       real(kind=c_float)  :: a(self%local_nrows, *), q(self%local_nrows, *)
     575             : #else
     576             :       real(kind=c_float)  :: a(self%local_nrows, self%local_ncols), q(self%local_nrows, self%local_ncols)
     577             : #endif
     578             :       real(kind=c_float)  :: ev(self%na)
     579             : #ifdef USE_FORTRAN2008
     580             :       integer, optional   :: error
     581             : #else
     582             :       integer             :: error
     583             : #endif
     584             :     end subroutine
     585             :   end interface
     586             : 
     587             : 
     588             :   !> \brief abstract definition of interface to solve double complex eigenvalue problem
     589             :   !>
     590             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
     591             :   !>  blocksize, the number of eigenvectors
     592             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     593             :   !>  with the class method "setup"
     594             :   !>
     595             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     596             :   !>  class method "set"
     597             :   !> Parameters
     598             :   !> \details
     599             :   !> \param   self        class(elpa_t), the ELPA object
     600             :   !> \param   a           double complex matrix a: defines the problem to solve
     601             :   !> \param   ev          double real: on output stores the eigenvalues
     602             :   !> \param   q           double complex matrix q: on output stores the eigenvalues
     603             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     604             :   abstract interface
     605             :     subroutine elpa_eigenvectors_dc_i(self, a, ev, q, error)
     606             :       use iso_c_binding
     607             :       import elpa_t
     608             :       implicit none
     609             :       class(elpa_t)                  :: self
     610             : 
     611             : #ifdef USE_ASSUMED_SIZE
     612             :       complex(kind=c_double_complex) :: a(self%local_nrows, *), q(self%local_nrows, *)
     613             : #else
     614             :       complex(kind=c_double_complex) :: a(self%local_nrows, self%local_ncols), q(self%local_nrows, self%local_ncols)
     615             : #endif
     616             :       real(kind=c_double)            :: ev(self%na)
     617             : #ifdef USE_FORTRAN2008
     618             :       integer, optional              :: error
     619             : #else
     620             :       integer                        :: error
     621             : #endif
     622             :     end subroutine
     623             :   end interface
     624             : 
     625             : 
     626             :   !> \brief abstract definition of interface to solve single complex eigenvalue problem
     627             :   !>
     628             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
     629             :   !>  blocksize, the number of eigenvectors
     630             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     631             :   !>  with the class method "setup"
     632             :   !>
     633             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     634             :   !>  class method "set"
     635             :   !> Parameters
     636             :   !> \details
     637             :   !> \param   self        class(elpa_t), the ELPA object
     638             :   !> \param   a           single complex matrix a: defines the problem to solve
     639             :   !> \param   ev          single real: on output stores the eigenvalues
     640             :   !> \param   q           single complex matrix q: on output stores the eigenvalues
     641             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     642             :   abstract interface
     643             :     subroutine elpa_eigenvectors_fc_i(self, a, ev, q, error)
     644             :       use iso_c_binding
     645             :       import elpa_t
     646             :       implicit none
     647             :       class(elpa_t)                 :: self
     648             : #ifdef USE_ASSUMED_SIZE
     649             :       complex(kind=c_float_complex) :: a(self%local_nrows, *), q(self%local_nrows, *)
     650             : #else
     651             :       complex(kind=c_float_complex) :: a(self%local_nrows, self%local_ncols), q(self%local_nrows, self%local_ncols)
     652             : #endif
     653             :       real(kind=c_float)            :: ev(self%na)
     654             : #ifdef USE_FORTRAN2008
     655             :       integer, optional             :: error
     656             : #else
     657             :       integer                       :: error
     658             : #endif
     659             :     end subroutine
     660             :   end interface
     661             : 
     662             : 
     663             :   !> \brief abstract definition of interface to solve double real eigenvalue problem
     664             :   !>
     665             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
     666             :   !>  blocksize, the number of eigenvectors
     667             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     668             :   !>  with the class method "setup"
     669             :   !>
     670             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     671             :   !>  class method "set"
     672             :   !> Parameters
     673             :   !> \details
     674             :   !> \param   self        class(elpa_t), the ELPA object
     675             :   !> \param   a           double real matrix a: defines the problem to solve
     676             :   !> \param   ev          double real: on output stores the eigenvalues
     677             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     678             :   abstract interface
     679             :     subroutine elpa_eigenvalues_d_i(self, a, ev, error)
     680             :       use iso_c_binding
     681             :       import elpa_t
     682             :       implicit none
     683             :       class(elpa_t)       :: self
     684             : #ifdef USE_ASSUMED_SIZE
     685             :       real(kind=c_double) :: a(self%local_nrows, *)
     686             : #else
     687             :       real(kind=c_double) :: a(self%local_nrows, self%local_ncols)
     688             : #endif
     689             :       real(kind=c_double) :: ev(self%na)
     690             : #ifdef USE_FORTRAN2008
     691             :       integer, optional   :: error
     692             : #else
     693             :       integer             :: error
     694             : #endif
     695             :     end subroutine
     696             :   end interface
     697             : 
     698             : 
     699             :   !> \brief abstract definition of interface to solve single real eigenvalue problem
     700             :   !>
     701             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
     702             :   !>  blocksize, the number of eigenvectors
     703             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     704             :   !>  with the class method "setup"
     705             :   !>
     706             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     707             :   !>  class method "set"
     708             :   !> Parameters
     709             :   !> \details
     710             :   !> \param   self        class(elpa_t), the ELPA object
     711             :   !> \param   a           single real matrix a: defines the problem to solve
     712             :   !> \param   ev          single real: on output stores the eigenvalues
     713             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     714             :   abstract interface
     715             :     subroutine elpa_eigenvalues_f_i(self, a, ev, error)
     716             :       use iso_c_binding
     717             :       import elpa_t
     718             :       implicit none
     719             :       class(elpa_t)       :: self
     720             : #ifdef USE_ASSUMED_SIZE
     721             :       real(kind=c_float)  :: a(self%local_nrows, *)
     722             : #else
     723             :       real(kind=c_float)  :: a(self%local_nrows, self%local_ncols)
     724             : #endif
     725             :       real(kind=c_float)  :: ev(self%na)
     726             : #ifdef USE_FORTRAN2008
     727             :       integer, optional   :: error
     728             : #else
     729             :       integer             :: error
     730             : #endif
     731             :     end subroutine
     732             :   end interface
     733             : 
     734             : 
     735             :   !> \brief abstract definition of interface to solve double complex eigenvalue problem
     736             :   !>
     737             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
     738             :   !>  blocksize, the number of eigenvectors
     739             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     740             :   !>  with the class method "setup"
     741             :   !>
     742             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     743             :   !>  class method "set"
     744             :   !> Parameters
     745             :   !> \details
     746             :   !> \param   self        class(elpa_t), the ELPA object
     747             :   !> \param   a           double complex matrix a: defines the problem to solve
     748             :   !> \param   ev          double real: on output stores the eigenvalues
     749             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     750             :   abstract interface
     751             :     subroutine elpa_eigenvalues_dc_i(self, a, ev, error)
     752             :       use iso_c_binding
     753             :       import elpa_t
     754             :       implicit none
     755             :       class(elpa_t)                  :: self
     756             : 
     757             : #ifdef USE_ASSUMED_SIZE
     758             :       complex(kind=c_double_complex) :: a(self%local_nrows, *)
     759             : #else
     760             :       complex(kind=c_double_complex) :: a(self%local_nrows, self%local_ncols)
     761             : #endif
     762             :       real(kind=c_double)            :: ev(self%na)
     763             : #ifdef USE_FORTRAN2008
     764             :       integer, optional              :: error
     765             : #else
     766             :       integer                        :: error
     767             : #endif
     768             :     end subroutine
     769             :   end interface
     770             : 
     771             : 
     772             :   !> \brief abstract definition of interface to solve single complex eigenvalue problem
     773             :   !>
     774             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
     775             :   !>  blocksize, the number of eigenvectors
     776             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     777             :   !>  with the class method "setup"
     778             :   !>
     779             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     780             :   !>  class method "set"
     781             :   !> Parameters
     782             :   !> \details
     783             :   !> \param   self        class(elpa_t), the ELPA object
     784             :   !> \param   a           single complex matrix a: defines the problem to solve
     785             :   !> \param   ev          single real: on output stores the eigenvalues
     786             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     787             :   abstract interface
     788             :     subroutine elpa_eigenvalues_fc_i(self, a, ev, error)
     789             :       use iso_c_binding
     790             :       import elpa_t
     791             :       implicit none
     792             :       class(elpa_t)                 :: self
     793             : #ifdef USE_ASSUMED_SIZE
     794             :       complex(kind=c_float_complex) :: a(self%local_nrows, *)
     795             : #else
     796             :       complex(kind=c_float_complex) :: a(self%local_nrows, self%local_ncols)
     797             : #endif
     798             :       real(kind=c_float)            :: ev(self%na)
     799             : #ifdef USE_FORTRAN2008
     800             :       integer, optional             :: error
     801             : #else
     802             :       integer                       :: error
     803             : #endif
     804             :     end subroutine
     805             :   end interface
     806             : 
     807             : #if 0
     808             :   !> \brief abstract definition of interface to solve double real generalized eigenvalue problem
     809             :   !>
     810             :   !>  The dimensions of the matrix a and b (locally ditributed and global), the block-cyclic distribution
     811             :   !>  blocksize, the number of eigenvectors
     812             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     813             :   !>  with the class method "setup"
     814             :   !>
     815             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     816             :   !>  class method "set"
     817             :   !> Parameters
     818             :   !> \details
     819             :   !> \param   self        class(elpa_t), the ELPA object
     820             :   !> \param   a           double real matrix a: defines the problem to solve
     821             :   !> \param   b           double real matrix b: defines the problem to solve
     822             :   !> \param   ev          double real: on output stores the eigenvalues
     823             :   !> \param   q           double real matrix q: on output stores the eigenvalues
     824             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     825             :   abstract interface
     826             :     subroutine elpa_generalized_eigenvectors_d_i(self, a, b, ev, q, sc_desc, error)
     827             :       use iso_c_binding
     828             :       use elpa_constants
     829             :       import elpa_t
     830             :       implicit none
     831             :       class(elpa_t)       :: self
     832             : #ifdef USE_ASSUMED_SIZE
     833             :       real(kind=c_double) :: a(self%local_nrows, *), b(self%local_nrows, *), q(self%local_nrows, *)
     834             : #else
     835             :       real(kind=c_double) :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols), &
     836             :                              q(self%local_nrows, self%local_ncols)
     837             : #endif
     838             :       real(kind=c_double) :: ev(self%na)
     839             :       integer             :: sc_desc(SC_DESC_LEN)
     840             : 
     841             :       integer, optional   :: error
     842             :     end subroutine
     843             :   end interface
     844             : 
     845             :   !> \brief abstract definition of interface to solve single real generalized eigenvalue problem
     846             :   !>
     847             :   !>  The dimensions of the matrix a and b(locally ditributed and global), the block-cyclic distribution
     848             :   !>  blocksize, the number of eigenvectors
     849             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     850             :   !>  with the class method "setup"
     851             :   !>
     852             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     853             :   !>  class method "set"
     854             :   !> Parameters
     855             :   !> \details
     856             :   !> \param   self        class(elpa_t), the ELPA object
     857             :   !> \param   a           single real matrix a: defines the problem to solve
     858             :   !> \param   b           single real matrix b: defines the problem to solve
     859             :   !> \param   ev          single real: on output stores the eigenvalues
     860             :   !> \param   q           single real matrix q: on output stores the eigenvalues
     861             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     862             :   abstract interface
     863             :     subroutine elpa_generalized_eigenvectors_f_i(self, a, b, ev, q, sc_desc, error)
     864             :       use iso_c_binding
     865             :       use elpa_constants
     866             :       import elpa_t
     867             :       implicit none
     868             :       class(elpa_t)       :: self
     869             : #ifdef USE_ASSUMED_SIZE
     870             :       real(kind=c_float)  :: a(self%local_nrows, *), b(self%local_nrows, *), q(self%local_nrows, *)
     871             : #else
     872             :       real(kind=c_float)  :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols), &
     873             :                              q(self%local_nrows, self%local_ncols)
     874             : #endif
     875             :       real(kind=c_float)  :: ev(self%na)
     876             :       integer             :: sc_desc(SC_DESC_LEN)
     877             : 
     878             :       integer, optional   :: error
     879             :     end subroutine
     880             :   end interface
     881             : 
     882             :   !> \brief abstract definition of interface to solve double complex generalized eigenvalue problem
     883             :   !>
     884             :   !>  The dimensions of the matrix a and b(locally ditributed and global), the block-cyclic distribution
     885             :   !>  blocksize, the number of eigenvectors
     886             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     887             :   !>  with the class method "setup"
     888             :   !>
     889             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     890             :   !>  class method "set"
     891             :   !> Parameters
     892             :   !> \details
     893             :   !> \param   self        class(elpa_t), the ELPA object
     894             :   !> \param   a           double complex matrix a: defines the problem to solve
     895             :   !> \param   b           double complex matrix b: defines the problem to solve
     896             :   !> \param   ev          double real: on output stores the eigenvalues
     897             :   !> \param   q           double complex matrix q: on output stores the eigenvalues
     898             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     899             :   abstract interface
     900             :     subroutine elpa_generalized_eigenvectors_dc_i(self, a, b, ev, q, sc_desc, error)
     901             :       use iso_c_binding
     902             :       use elpa_constants
     903             :       import elpa_t
     904             :       implicit none
     905             :       class(elpa_t)                  :: self
     906             : 
     907             : #ifdef USE_ASSUMED_SIZE
     908             :       complex(kind=c_double_complex) :: a(self%local_nrows, *), b(self%local_nrows, *), q(self%local_nrows, *)
     909             : #else
     910             :       complex(kind=c_double_complex) :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols), &
     911             :                                         q(self%local_nrows, self%local_ncols)
     912             : #endif
     913             :       real(kind=c_double)            :: ev(self%na)
     914             :       integer                        :: sc_desc(SC_DESC_LEN)
     915             : 
     916             :       integer, optional              :: error
     917             :     end subroutine
     918             :   end interface
     919             : 
     920             :   !> \brief abstract definition of interface to solve single complex generalized eigenvalue problem
     921             :   !>
     922             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
     923             :   !>  blocksize, the number of eigenvectors
     924             :   !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
     925             :   !>  with the class method "setup"
     926             :   !>
     927             :   !>  It is possible to change the behaviour of the method by setting tunable parameters with the
     928             :   !>  class method "set"
     929             :   !> Parameters
     930             :   !> \details
     931             :   !> \param   self        class(elpa_t), the ELPA object
     932             :   !> \param   a           single complex matrix a: defines the problem to solve
     933             :   !> \param   b           single complex matrix b: defines the problem to solve
     934             :   !> \param   ev          single real: on output stores the eigenvalues
     935             :   !> \param   q           single complex matrix q: on output stores the eigenvalues
     936             :   !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
     937             :   abstract interface
     938             :     subroutine elpa_generalized_eigenvectors_fc_i(self, a, b, ev, q, sc_desc, error)
     939             :       use iso_c_binding
     940             :       use elpa_constants
     941             :       import elpa_t
     942             :       implicit none
     943             :       class(elpa_t)                 :: self
     944             : #ifdef USE_ASSUMED_SIZE
     945             :       complex(kind=c_float_complex) :: a(self%local_nrows, *), b(self%local_nrows, *), q(self%local_nrows, *)
     946             : #else
     947             :       complex(kind=c_float_complex) :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols), &
     948             :                                        q(self%local_nrows, self%local_ncols)
     949             : #endif
     950             :       real(kind=c_float)            :: ev(self%na)
     951             :       integer                       :: sc_desc(SC_DESC_LEN)
     952             : 
     953             :       integer, optional             :: error
     954             :     end subroutine
     955             :   end interface
     956             : #endif
     957             : 
     958             : 
     959             :   !> \brief abstract definition of interface to compute C : = A**T * B for double real matrices
     960             :   !>         where   A is a square matrix (self%a,self%na) which is optionally upper or lower triangular
     961             :   !>                 B is a (self%na,ncb) matrix
     962             :   !>                 C is a (self%na,ncb) matrix where optionally only the upper or lower
     963             :   !>                   triangle may be computed
     964             :   !>
     965             :   !> the MPI commicators are already known to the type. Thus the class method "setup" must be called
     966             :   !> BEFORE this method is used
     967             :   !> \details
     968             :   !>
     969             :   !> \param   self                class(elpa_t), the ELPA object
     970             :   !> \param  uplo_a               'U' if A is upper triangular
     971             :   !>                              'L' if A is lower triangular
     972             :   !>                              anything else if A is a full matrix
     973             :   !>                              Please note: This pertains to the original A (as set in the calling program)
     974             :   !>                                           whereas the transpose of A is used for calculations
     975             :   !>                              If uplo_a is 'U' or 'L', the other triangle is not used at all,
     976             :   !>                              i.e. it may contain arbitrary numbers
     977             :   !> \param uplo_c                'U' if only the upper diagonal part of C is needed
     978             :   !>                              'L' if only the upper diagonal part of C is needed
     979             :   !>                              anything else if the full matrix C is needed
     980             :   !>                              Please note: Even when uplo_c is 'U' or 'L', the other triangle may be
     981             :   !>                                            written to a certain extent, i.e. one shouldn't rely on the content there!
     982             :   !> \param ncb                   Number of columns  of global matrices B and C
     983             :   !> \param a                     matrix a
     984             :   !> \param self%local_nrows      number of rows of local (sub) matrix a, set with method set("local_nrows,value")
     985             :   !> \param self%local_ncols      number of columns of local (sub) matrix a, set with method set("local_ncols,value")
     986             :   !> \param b                     matrix b
     987             :   !> \param nrows_b               number of rows of local (sub) matrix b
     988             :   !> \param ncols_b               number of columns of local (sub) matrix b
     989             :   !> \param nblk                  blocksize of cyclic distribution, must be the same in both directions!
     990             :   !> \param c                     matrix c
     991             :   !> \param nrows_c               number of rows of local (sub) matrix c
     992             :   !> \param ncols_c               number of columns of local (sub) matrix c
     993             :   !> \param error                 optional argument, error code which can be queried with elpa_strerr
     994             :   abstract interface
     995             :     subroutine elpa_hermitian_multiply_d_i (self,uplo_a, uplo_c, ncb, a, b, nrows_b, ncols_b, &
     996             :                                           c, nrows_c, ncols_c, error)
     997             :       use iso_c_binding
     998             :       import elpa_t
     999             :       implicit none
    1000             :       class(elpa_t)                   :: self
    1001             :       character*1                     :: uplo_a, uplo_c
    1002             :       integer(kind=c_int), intent(in) :: nrows_b, ncols_b, nrows_c, ncols_c, ncb
    1003             : #ifdef USE_ASSUMED_SIZE
    1004             :       real(kind=c_double)             :: a(self%local_nrows,*), b(nrows_b,*), c(nrows_c,*)
    1005             : #else
    1006             :       real(kind=c_double)             :: a(self%local_nrows,self%local_ncols), b(nrows_b,ncols_b), c(nrows_c,ncols_c)
    1007             : #endif
    1008             : #ifdef USE_FORTRAN2008
    1009             :       integer, optional               :: error
    1010             : #else
    1011             :       integer                         :: error
    1012             : #endif
    1013             :     end subroutine
    1014             :   end interface
    1015             : 
    1016             : 
    1017             :   !> \brief abstract definition of interface to compute C : = A**T * B
    1018             :   !>         where   A is a square matrix (self%na,self%na) which is optionally upper or lower triangular
    1019             :   !>                 B is a (self%na,ncb) matrix
    1020             :   !>                 C is a (self%na,ncb) matrix where optionally only the upper or lower
    1021             :   !>                   triangle may be computed
    1022             :   !>
    1023             :   !> the MPI commicators are already known to the type. Thus the class method "setup" must be called
    1024             :   !> BEFORE this method is used
    1025             :   !> \details
    1026             :   !>
    1027             :   !> \param   self                class(elpa_t), the ELPA object
    1028             :   !> \param  uplo_a               'U' if A is upper triangular
    1029             :   !>                              'L' if A is lower triangular
    1030             :   !>                              anything else if A is a full matrix
    1031             :   !>                              Please note: This pertains to the original A (as set in the calling program)
    1032             :   !>                                           whereas the transpose of A is used for calculations
    1033             :   !>                              If uplo_a is 'U' or 'L', the other triangle is not used at all,
    1034             :   !>                              i.e. it may contain arbitrary numbers
    1035             :   !> \param uplo_c                'U' if only the upper diagonal part of C is needed
    1036             :   !>                              'L' if only the upper diagonal part of C is needed
    1037             :   !>                              anything else if the full matrix C is needed
    1038             :   !>                              Please note: Even when uplo_c is 'U' or 'L', the other triangle may be
    1039             :   !>                                            written to a certain extent, i.e. one shouldn't rely on the content there!
    1040             :   !> \param ncb                   Number of columns  of global matrices B and C
    1041             :   !> \param a                     matrix a
    1042             :   !> \param self%local_nrows      number of rows of local (sub) matrix a, set with method set("local_nrows",value)
    1043             :   !> \param self%local_ncols      number of columns of local (sub) matrix a, set with method set("local_nrows",value)
    1044             :   !> \param b                     matrix b
    1045             :   !> \param nrows_b               number of rows of local (sub) matrix b
    1046             :   !> \param ncols_b               number of columns of local (sub) matrix b
    1047             :   !> \param nblk                  blocksize of cyclic distribution, must be the same in both directions!
    1048             :   !> \param c                     matrix c
    1049             :   !> \param nrows_c               number of rows of local (sub) matrix c
    1050             :   !> \param ncols_c               number of columns of local (sub) matrix c
    1051             :   !> \param error                 optional argument, error code which can be queried with elpa_strerr
    1052             :   abstract interface
    1053             :     subroutine elpa_hermitian_multiply_f_i (self,uplo_a, uplo_c, ncb, a, b, nrows_b, ncols_b, &
    1054             :                                           c, nrows_c, ncols_c, error)
    1055             :       use iso_c_binding
    1056             :       import elpa_t
    1057             :       implicit none
    1058             :       class(elpa_t)                   :: self
    1059             :       character*1                     :: uplo_a, uplo_c
    1060             :       integer(kind=c_int), intent(in) :: nrows_b, ncols_b, nrows_c, ncols_c, ncb
    1061             : #ifdef USE_ASSUMED_SIZE
    1062             :       real(kind=c_float)              :: a(self%local_nrows,*), b(nrows_b,*), c(nrows_c,*)
    1063             : #else
    1064             :       real(kind=c_float)              :: a(self%local_nrows,self%local_ncols), b(nrows_b,ncols_b), c(nrows_c,ncols_c)
    1065             : #endif
    1066             : #ifdef USE_FORTRAN2008
    1067             :       integer, optional               :: error
    1068             : #else
    1069             :       integer                         :: error
    1070             : #endif
    1071             :     end subroutine
    1072             :   end interface
    1073             : 
    1074             : 
    1075             :   !> \brief abstract definition of interface to compute C : = A**H * B
    1076             :   !>         where   A is a square matrix (self%na,self%a) which is optionally upper or lower triangular
    1077             :   !>                 B is a (self%na,ncb) matrix
    1078             :   !>                 C is a (self%na,ncb) matrix where optionally only the upper or lower
    1079             :   !>                   triangle may be computed
    1080             :   !>
    1081             :   !> the MPI commicators are already known to the type. Thus the class method "setup" must be called
    1082             :   !> BEFORE this method is used
    1083             :   !> \details
    1084             :   !>
    1085             :   !> \param   self                class(elpa_t), the ELPA object
    1086             :   !> \param  uplo_a               'U' if A is upper triangular
    1087             :   !>                              'L' if A is lower triangular
    1088             :   !>                              anything else if A is a full matrix
    1089             :   !>                              Please note: This pertains to the original A (as set in the calling program)
    1090             :   !>                                           whereas the transpose of A is used for calculations
    1091             :   !>                              If uplo_a is 'U' or 'L', the other triangle is not used at all,
    1092             :   !>                              i.e. it may contain arbitrary numbers
    1093             :   !> \param uplo_c                'U' if only the upper diagonal part of C is needed
    1094             :   !>                              'L' if only the upper diagonal part of C is needed
    1095             :   !>                              anything else if the full matrix C is needed
    1096             :   !>                              Please note: Even when uplo_c is 'U' or 'L', the other triangle may be
    1097             :   !>                                            written to a certain extent, i.e. one shouldn't rely on the content there!
    1098             :   !> \param ncb                   Number of columns  of global matrices B and C
    1099             :   !> \param a                     matrix a
    1100             :   !> \param self%local_nrows      number of rows of local (sub) matrix a, set with the method set("local_nrows",value)
    1101             :   !> \param self%local_ncols      number of columns of local (sub) matrix a, set with the method set("local_ncols",value)
    1102             :   !> \param b                     matrix b
    1103             :   !> \param nrows_b               number of rows of local (sub) matrix b
    1104             :   !> \param ncols_b               number of columns of local (sub) matrix b
    1105             :   !> \param nblk                  blocksize of cyclic distribution, must be the same in both directions!
    1106             :   !> \param c                     matrix c
    1107             :   !> \param nrows_c               number of rows of local (sub) matrix c
    1108             :   !> \param ncols_c               number of columns of local (sub) matrix c
    1109             :   !> \param error                 optional argument, error code which can be queried with elpa_strerr
    1110             :   abstract interface
    1111             :     subroutine elpa_hermitian_multiply_dc_i (self,uplo_a, uplo_c, ncb, a, b, nrows_b, ncols_b, &
    1112             :                                           c, nrows_c, ncols_c, error)
    1113             :       use iso_c_binding
    1114             :       import elpa_t
    1115             :       implicit none
    1116             :       class(elpa_t)                   :: self
    1117             :       character*1                     :: uplo_a, uplo_c
    1118             :       integer(kind=c_int), intent(in) :: nrows_b, ncols_b, nrows_c, ncols_c, ncb
    1119             : #ifdef USE_ASSUMED_SIZE
    1120             :       complex(kind=c_double_complex)  :: a(self%local_nrows,*), b(nrows_b,*), c(nrows_c,*)
    1121             : #else
    1122             :       complex(kind=c_double_complex)  :: a(self%local_nrows,self%local_ncols), b(nrows_b,ncols_b), c(nrows_c,ncols_c)
    1123             : #endif
    1124             : #ifdef USE_FORTRAN2008
    1125             :       integer, optional               :: error
    1126             : #else
    1127             :       integer                         :: error
    1128             : #endif
    1129             :     end subroutine
    1130             :   end interface
    1131             : 
    1132             : 
    1133             :   !> \brief abstract definition of interface to compute C : = A**H * B
    1134             :   !>         where   A is a square matrix (self%na,self%na) which is optionally upper or lower triangular
    1135             :   !>                 B is a (self%na,ncb) matrix
    1136             :   !>                 C is a (self%na,ncb) matrix where optionally only the upper or lower
    1137             :   !>                   triangle may be computed
    1138             :   !>
    1139             :   !> the MPI commicators are already known to the type. Thus the class method "setup" must be called
    1140             :   !> BEFORE this method is used
    1141             :   !> \details
    1142             :   !>
    1143             :   !> \param   self                class(elpa_t), the ELPA object
    1144             :   !> \param  uplo_a               'U' if A is upper triangular
    1145             :   !>                              'L' if A is lower triangular
    1146             :   !>                              anything else if A is a full matrix
    1147             :   !>                              Please note: This pertains to the original A (as set in the calling program)
    1148             :   !>                                           whereas the transpose of A is used for calculations
    1149             :   !>                              If uplo_a is 'U' or 'L', the other triangle is not used at all,
    1150             :   !>                              i.e. it may contain arbitrary numbers
    1151             :   !> \param uplo_c                'U' if only the upper diagonal part of C is needed
    1152             :   !>                              'L' if only the upper diagonal part of C is needed
    1153             :   !>                              anything else if the full matrix C is needed
    1154             :   !>                              Please note: Even when uplo_c is 'U' or 'L', the other triangle may be
    1155             :   !>                                            written to a certain extent, i.e. one shouldn't rely on the content there!
    1156             :   !> \param ncb                   Number of columns  of global matrices B and C
    1157             :   !> \param a                     matrix a
    1158             :   !> \param self%local_nrows      number of rows of local (sub) matrix a, set with class method set("local_nrows",value)
    1159             :   !> \param self%local_ncols      number of columns of local (sub) matrix a, set with class method set("local_ncols",value)
    1160             :   !> \param b                     matrix b
    1161             :   !> \param nrows_b               number of rows of local (sub) matrix b
    1162             :   !> \param ncols_b               number of columns of local (sub) matrix b
    1163             :   !> \param nblk                  blocksize of cyclic distribution, must be the same in both directions!
    1164             :   !> \param c                     matrix c
    1165             :   !> \param nrows_c               number of rows of local (sub) matrix c
    1166             :   !> \param ncols_c               number of columns of local (sub) matrix c
    1167             :   !> \param error                 optional argument, error code which can be queried with elpa_strerr
    1168             :   abstract interface
    1169             :     subroutine elpa_hermitian_multiply_fc_i (self, uplo_a, uplo_c, ncb, a, b, nrows_b, ncols_b, &
    1170             :                                           c, nrows_c, ncols_c, error)
    1171             :       use iso_c_binding
    1172             :       import elpa_t
    1173             :       implicit none
    1174             :       class(elpa_t)                   :: self
    1175             :       character*1                     :: uplo_a, uplo_c
    1176             :       integer(kind=c_int), intent(in) :: nrows_b, ncols_b, nrows_c, ncols_c, ncb
    1177             : #ifdef USE_ASSUMED_SIZE
    1178             :       complex(kind=c_float_complex)   :: a(self%local_nrows,*), b(nrows_b,*), c(nrows_c,*)
    1179             : #else
    1180             :       complex(kind=c_float_complex)   :: a(self%local_nrows,self%local_ncols), b(nrows_b,ncols_b), c(nrows_c,ncols_c)
    1181             : #endif
    1182             : #ifdef USE_FORTRAN2008
    1183             :       integer, optional               :: error
    1184             : #else
    1185             :       integer                         :: error
    1186             : #endif
    1187             :     end subroutine
    1188             :   end interface
    1189             : 
    1190             : 
    1191             :   !> \brief abstract definition of interface to do a cholesky decomposition of a double real matrix
    1192             :   !>
    1193             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1194             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1195             :   !>  with the class method "setup"
    1196             :   !>
    1197             :   !> Parameters
    1198             :   !> \param   self        class(elpa_t), the ELPA object
    1199             :   !> \param   a           double real matrix: the matrix to be decomposed
    1200             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1201             :   abstract interface
    1202             :     subroutine elpa_cholesky_d_i (self, a, error)
    1203             :       use iso_c_binding
    1204             :       import elpa_t
    1205             :       implicit none
    1206             :       class(elpa_t)                   :: self
    1207             : #ifdef USE_ASSUMED_SIZE
    1208             :       real(kind=c_double)             :: a(self%local_nrows,*)
    1209             : #else
    1210             :       real(kind=c_double)             :: a(self%local_nrows,self%local_ncols)
    1211             : #endif
    1212             : #ifdef USE_FORTRAN2008
    1213             :       integer, optional               :: error
    1214             : #else
    1215             :       integer                         :: error
    1216             : #endif
    1217             :     end subroutine
    1218             :   end interface
    1219             : 
    1220             : 
    1221             :   !> \brief abstract definition of interface to do a cholesky decomposition of a single real matrix
    1222             :   !>
    1223             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1224             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1225             :   !>  with the class method "setup"
    1226             :   !>
    1227             :   !> Parameters
    1228             :   !> \param   self        class(elpa_t), the ELPA object
    1229             :   !> \param   a           single real matrix: the matrix to be decomposed
    1230             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1231             :   abstract interface
    1232             :     subroutine elpa_cholesky_f_i(self, a, error)
    1233             :       use iso_c_binding
    1234             :       import elpa_t
    1235             :       implicit none
    1236             :       class(elpa_t)                   :: self
    1237             : #ifdef USE_ASSUMED_SIZE
    1238             :       real(kind=c_float)              :: a(self%local_nrows,*)
    1239             : #else
    1240             :       real(kind=c_float)              :: a(self%local_nrows,self%local_ncols)
    1241             : #endif
    1242             : #ifdef USE_FORTRAN2008
    1243             :       integer, optional               :: error
    1244             : #else
    1245             :       integer                         :: error
    1246             : #endif
    1247             :     end subroutine
    1248             :   end interface
    1249             : 
    1250             : 
    1251             :   !> \brief abstract definition of interface to do a cholesky decomposition of a double complex matrix
    1252             :   !>
    1253             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1254             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1255             :   !>  with the class method "setup"
    1256             :   !>
    1257             :   !> Parameters
    1258             :   !> \param   self        class(elpa_t), the ELPA object
    1259             :   !> \param   a           double complex matrix: the matrix to be decomposed
    1260             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1261             :   abstract interface
    1262             :     subroutine elpa_cholesky_dc_i (self, a, error)
    1263             :       use iso_c_binding
    1264             :       import elpa_t
    1265             :       implicit none
    1266             :       class(elpa_t)                   :: self
    1267             : #ifdef USE_ASSUMED_SIZE
    1268             :       complex(kind=c_double_complex)  :: a(self%local_nrows,*)
    1269             : #else
    1270             :       complex(kind=c_double_complex)  :: a(self%local_nrows,self%local_ncols)
    1271             : #endif
    1272             : #ifdef USE_FORTRAN2008
    1273             :       integer, optional               :: error
    1274             : #else
    1275             :       integer                         :: error
    1276             : #endif
    1277             :     end subroutine
    1278             :   end interface
    1279             : 
    1280             : 
    1281             :   !> \brief abstract definition of interface to do a cholesky decomposition of a single complex matrix
    1282             :   !>
    1283             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1284             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1285             :   !>  with the class method "setup"
    1286             :   !>
    1287             :   !> Parameters
    1288             :   !> \param   self        class(elpa_t), the ELPA object
    1289             :   !> \param   a           single complex matrix: the matrix to be decomposed
    1290             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1291             :   abstract interface
    1292             :     subroutine elpa_cholesky_fc_i (self, a, error)
    1293             :       use iso_c_binding
    1294             :       import elpa_t
    1295             :       implicit none
    1296             :       class(elpa_t)                   :: self
    1297             : #ifdef USE_ASSUMED_SIZE
    1298             :       complex(kind=c_float_complex)   :: a(self%local_nrows,*)
    1299             : #else
    1300             :       complex(kind=c_float_complex)   :: a(self%local_nrows,self%local_ncols)
    1301             : #endif
    1302             : #ifdef USE_FORTRAN2008
    1303             :       integer, optional               :: error
    1304             : #else
    1305             :       integer                         :: error
    1306             : #endif
    1307             :     end subroutine
    1308             :   end interface
    1309             : 
    1310             : 
    1311             :   !> \brief abstract definition of interface to invert a triangular double real matrix
    1312             :   !>
    1313             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1314             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1315             :   !>  with the class method "setup"
    1316             :   !>
    1317             :   !> Parameters
    1318             :   !> \param   self        class(elpa_t), the ELPA object
    1319             :   !> \param   a           double real matrix: the matrix to be inverted
    1320             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1321             :   abstract interface
    1322             :     subroutine elpa_invert_trm_d_i (self, a, error)
    1323             :       use iso_c_binding
    1324             :       import elpa_t
    1325             :       implicit none
    1326             :       class(elpa_t)                   :: self
    1327             : #ifdef USE_ASSUMED_SIZE
    1328             :       real(kind=c_double)             :: a(self%local_nrows,*)
    1329             : #else
    1330             :       real(kind=c_double)             :: a(self%local_nrows,self%local_ncols)
    1331             : #endif
    1332             : #ifdef USE_FORTRAN2008
    1333             :       integer, optional               :: error
    1334             : #else
    1335             :       integer                         :: error
    1336             : #endif
    1337             :     end subroutine
    1338             :   end interface
    1339             : 
    1340             : 
    1341             :   !> \brief abstract definition of interface to invert a triangular single real matrix
    1342             :   !> Parameters
    1343             :   !>
    1344             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1345             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1346             :   !>  with the class method "setup"
    1347             :   !>
    1348             :   !> \param   self        class(elpa_t), the ELPA object
    1349             :   !> \param   a           single real matrix: the matrix to be inverted
    1350             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1351             :   abstract interface
    1352             :     subroutine elpa_invert_trm_f_i (self, a, error)
    1353             :       use iso_c_binding
    1354             :       import elpa_t
    1355             :       implicit none
    1356             :       class(elpa_t)                   :: self
    1357             : #ifdef USE_ASSUMED_SIZE
    1358             :       real(kind=c_float)              :: a(self%local_nrows,*)
    1359             : #else
    1360             :       real(kind=c_float)              :: a(self%local_nrows,self%local_ncols)
    1361             : #endif
    1362             : #ifdef USE_FORTRAN2008
    1363             :       integer, optional               :: error
    1364             : #else
    1365             :       integer                         :: error
    1366             : #endif
    1367             :     end subroutine
    1368             :   end interface
    1369             : 
    1370             : 
    1371             :   !> \brief abstract definition of interface to invert a triangular double complex matrix
    1372             :   !>
    1373             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1374             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1375             :   !>  with the class method "setup"
    1376             :   !>
    1377             :   !> Parameters
    1378             :   !> \param   self        class(elpa_t), the ELPA object
    1379             :   !> \param   a           double complex matrix: the matrix to be inverted
    1380             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1381             :   abstract interface
    1382             :     subroutine elpa_invert_trm_dc_i (self, a, error)
    1383             :       use iso_c_binding
    1384             :       import elpa_t
    1385             :       implicit none
    1386             :       class(elpa_t)                   :: self
    1387             : #ifdef USE_ASSUMED_SIZE
    1388             :       complex(kind=c_double_complex)  :: a(self%local_nrows,*)
    1389             : #else
    1390             :       complex(kind=c_double_complex)  :: a(self%local_nrows,self%local_ncols)
    1391             : #endif
    1392             : #ifdef USE_FORTRAN2008
    1393             :       integer, optional               :: error
    1394             : #else
    1395             :       integer                         :: error
    1396             : #endif
    1397             :     end subroutine
    1398             :   end interface
    1399             : 
    1400             : 
    1401             :   !> \brief abstract definition of interface to invert a triangular single complex matrix
    1402             :   !>
    1403             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1404             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1405             :   !>  with the class method "setup"
    1406             :   !>
    1407             :   !> Parameters
    1408             :   !> \param   self        class(elpa_t), the ELPA object
    1409             :   !> \param   a           single complex matrix: the matrix to be inverted
    1410             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1411             :   abstract interface
    1412             :     subroutine elpa_invert_trm_fc_i (self, a, error)
    1413             :       use iso_c_binding
    1414             :       import elpa_t
    1415             :       implicit none
    1416             :       class(elpa_t)                   :: self
    1417             : #ifdef USE_ASSUMED_SIZE
    1418             :       complex(kind=c_float_complex)   :: a(self%local_nrows,*)
    1419             : #else
    1420             :       complex(kind=c_float_complex)   :: a(self%local_nrows,self%local_ncols)
    1421             : #endif
    1422             : #ifdef USE_FORTRAN2008
    1423             :       integer, optional               :: error
    1424             : #else
    1425             :       integer                         :: error
    1426             : #endif
    1427             :     end subroutine
    1428             :   end interface
    1429             : 
    1430             : 
    1431             :   !> \brief abstract definition of interface to solve the eigenvalue problem for a double-precision real valued tridiangular matrix
    1432             :   !>
    1433             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1434             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1435             :   !>  with the class method "setup"
    1436             :   !>
    1437             :   !> Parameters
    1438             :   !> \param   self        class(elpa_t), the ELPA object
    1439             :   !> \param   d           double real 1d array: the diagonal elements of a matrix defined in setup, on output the eigenvalues
    1440             :   !>                      in ascending order
    1441             :   !> \param   e           double real 1d array: the subdiagonal elements of a matrix defined in setup
    1442             :   !> \param   q           double real matrix: on output contains the eigenvectors
    1443             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1444             :   abstract interface
    1445             :     subroutine elpa_solve_tridiagonal_d_i (self, d, e, q, error)
    1446             :       use iso_c_binding
    1447             :       import elpa_t
    1448             :       implicit none
    1449             :       class(elpa_t)                   :: self
    1450             :       real(kind=c_double)             :: d(self%na), e(self%na)
    1451             : #ifdef USE_ASSUMED_SIZE
    1452             :       real(kind=c_double)             :: q(self%local_nrows,*)
    1453             : #else
    1454             :       real(kind=c_double)             :: q(self%local_nrows,self%local_ncols)
    1455             : #endif
    1456             : #ifdef USE_FORTRAN2008
    1457             :       integer, optional               :: error
    1458             : #else
    1459             :       integer                         :: error
    1460             : #endif
    1461             :     end subroutine
    1462             :   end interface
    1463             : 
    1464             : 
    1465             :   !> \brief abstract definition of interface to solve the eigenvalue problem for a single-precision real valued tridiangular matrix
    1466             :   !>
    1467             :   !>  The dimensions of the matrix a (locally ditributed and global), the block-cylic-distribution
    1468             :   !>  block size, and the MPI communicators are already known to the object and MUST be set BEFORE
    1469             :   !>  with the class method "setup"
    1470             :   !>
    1471             :   !> Parameters
    1472             :   !> \param   self        class(elpa_t), the ELPA object
    1473             :   !> \param   d           single real 1d array: the diagonal elements of a matrix defined in setup, on output the eigenvalues
    1474             :   !>                      in ascending order
    1475             :   !> \param   e           single real 1d array: the subdiagonal elements of a matrix defined in setup
    1476             :   !> \param   q           single real matrix: on output contains the eigenvectors
    1477             :   !> \param   error       integer, optional : error code, which can be queried with elpa_strerr
    1478             :   abstract interface
    1479             :     subroutine elpa_solve_tridiagonal_f_i (self, d, e, q, error)
    1480             :       use iso_c_binding
    1481             :       import elpa_t
    1482             :       implicit none
    1483             :       class(elpa_t)                   :: self
    1484             :       real(kind=c_float)              :: d(self%na), e(self%na)
    1485             : #ifdef USE_ASSUMED_SIZE
    1486             :       real(kind=c_float)              :: q(self%local_nrows,*)
    1487             : #else
    1488             :       real(kind=c_float)              :: q(self%local_nrows,self%local_ncols)
    1489             : #endif
    1490             : #ifdef USE_FORTRAN2008
    1491             :       integer, optional               :: error
    1492             : #else
    1493             :       integer                         :: error
    1494             : #endif
    1495             :     end subroutine
    1496             :   end interface
    1497             : 
    1498             : 
    1499             :   !> \brief abstract definition of interface to destroy an ELPA object
    1500             :   !> Parameters
    1501             :   !> \param   self        class(elpa_t), the ELPA object
    1502             :   abstract interface
    1503             :     subroutine elpa_destroy_i(self)
    1504             :       import elpa_t
    1505             :       implicit none
    1506             :       class(elpa_t) :: self
    1507             :     end subroutine
    1508             :   end interface
    1509             : 
    1510             :  
    1511             :   !> \brief abstract definition of interface to print the autotuning state
    1512             :   !> Parameters
    1513             :   !> \param   self        class(elpa_autotune_t): the ELPA autotune object
    1514             :   abstract interface
    1515             :     subroutine elpa_autotune_print_i(self)
    1516             :       import elpa_autotune_t
    1517             :       implicit none
    1518             :       class(elpa_autotune_t), intent(in) :: self
    1519             :     end subroutine
    1520             :   end interface
    1521             : 
    1522             :  
    1523             :   !> \brief abstract definition of interface to destroy the autotuning state
    1524             :   !> Parameters
    1525             :   !> \param   self        class(elpa_autotune_t): the ELPA autotune object
    1526             :   abstract interface
    1527             :     subroutine elpa_autotune_destroy_i(self)
    1528             :       import elpa_autotune_t
    1529             :       implicit none
    1530             :       class(elpa_autotune_t), intent(inout) :: self
    1531             :     end subroutine
    1532             :   end interface
    1533             : 
    1534             : 
    1535             :   contains
    1536             : 
    1537             : 
    1538             :     !> \brief function to intialize the ELPA library
    1539             :     !> Parameters
    1540             :     !> \param   api_version integer: api_version that ELPA should use
    1541             :     !> \result  error       integer: error code, which can be queried with elpa_strerr
    1542             :     !
    1543             :     !c> int elpa_init(int api_version);
    1544       21696 :     function elpa_init(api_version) result(error) bind(C, name="elpa_init")
    1545             :       use elpa_utilities, only : error_unit
    1546             :       use iso_c_binding
    1547             :       integer(kind=c_int), intent(in), value :: api_version
    1548             :       integer(kind=c_int)                    :: error
    1549             : 
    1550       21696 :       if (earliest_api_version <= api_version .and. api_version <= current_api_version) then
    1551       21696 :         initDone = .true.
    1552       21696 :         api_version_set = api_version
    1553       21696 :         error = ELPA_OK
    1554             :       else
    1555           0 :         write(error_unit, "(a,i0,a)") "ELPA: Error API version ", api_version," is not supported by this library"
    1556           0 :         error = ELPA_ERROR
    1557             :       endif
    1558       21696 :     end function
    1559             : 
    1560             : 
    1561             :     !> \brief function to check whether the ELPA library has been correctly initialised
    1562             :     !> Parameters
    1563             :     !> \result  state      integer: state is either ELPA_OK or ELPA_ERROR, which can be queried with elpa_strerr
    1564       21312 :     function elpa_initialized() result(state)
    1565             :       integer :: state
    1566       21312 :       if (initDone) then
    1567       21312 :         state = ELPA_OK
    1568             :       else
    1569           0 :         state = ELPA_ERROR
    1570             :       endif
    1571       21312 :     end function
    1572             : 
    1573           0 :     function elpa_get_api_version() result(api_version)
    1574             :        integer :: api_version
    1575             : 
    1576           0 :        api_version = api_version_set
    1577           0 :     end function
    1578             : 
    1579             : 
    1580             :     !> \brief subroutine to uninit the ELPA library. Does nothing at the moment. Might do sth. later
    1581             :     !
    1582             :     !c> void elpa_uninit(void);
    1583       21120 :     subroutine elpa_uninit() bind(C, name="elpa_uninit")
    1584       21120 :     end subroutine
    1585             : 
    1586             : 
    1587             :     !> \brief helper function for error strings
    1588             :     !> Parameters
    1589             :     !> \param   elpa_error  integer: error code to querry
    1590             :     !> \result  string      string:  error string
    1591           0 :     function elpa_strerr(elpa_error) result(string)
    1592             :       integer, intent(in) :: elpa_error
    1593             :       character(kind=C_CHAR, len=elpa_strlen_c(elpa_strerr_c(elpa_error))), pointer :: string
    1594           0 :       call c_f_pointer(elpa_strerr_c(elpa_error), string)
    1595           0 :     end function
    1596             : 
    1597             : 
    1598             :     !> \brief helper function for c strings
    1599             :     !> Parameters
    1600             :     !> \param   ptr         type(c_ptr)
    1601             :     !> \result  string      string
    1602        1728 :     function elpa_c_string(ptr) result(string)
    1603             :       use, intrinsic :: iso_c_binding
    1604             :       type(c_ptr), intent(in) :: ptr
    1605             :       character(kind=c_char, len=elpa_strlen_c(ptr)), pointer :: string
    1606        1728 :       call c_f_pointer(ptr, string)
    1607        1728 :     end function
    1608             : 
    1609             : 
    1610             :     !> \brief function to convert an integer in its string representation
    1611             :     !> Parameters
    1612             :     !> \param   name        string: the key
    1613             :     !> \param   value       integer: the value correponding to the key
    1614             :     !> \param   error       integer, optional: error code, which can be queried with elpa_strerr()
    1615             :     !> \result  string      string: the string representation
    1616       78112 :     function elpa_int_value_to_string(name, value, error) result(string)
    1617             :       use elpa_utilities, only : error_unit
    1618             :       implicit none
    1619             :       character(kind=c_char, len=*), intent(in) :: name
    1620             :       integer(kind=c_int), intent(in) :: value
    1621             :       integer(kind=c_int), intent(out), optional :: error
    1622             : 
    1623             : #ifdef PGI_VARIABLE_STRING_BUG
    1624             :       character(kind=c_char, len=elpa_int_value_to_strlen_c(name // C_NULL_CHAR, value)), pointer :: string_ptr
    1625             :       character(kind=c_char, len=elpa_int_value_to_strlen_c(name // C_NULL_CHAR, value)) :: string
    1626             : #else
    1627             :       character(kind=c_char, len=elpa_int_value_to_strlen_c(name // C_NULL_CHAR, value)), pointer :: string
    1628             : #endif
    1629             : 
    1630             :       integer(kind=c_int) :: actual_error
    1631             :       type(c_ptr) :: ptr
    1632             : 
    1633       78112 :       actual_error = elpa_int_value_to_string_c(name // C_NULL_CHAR, value, ptr)
    1634       78112 :       if (c_associated(ptr)) then
    1635             : #ifdef PGI_VARIABLE_STRING_BUG
    1636             :         call c_f_pointer(ptr, string_ptr)
    1637             :         string = string_ptr
    1638             : #else
    1639       78112 :         call c_f_pointer(ptr, string)
    1640             : #endif
    1641             :       else
    1642             : #ifdef PGI_VARIABLE_STRING_BUG
    1643             :         nullify(string_ptr)
    1644             : #else
    1645           0 :         nullify(string)
    1646             : #endif
    1647             :       endif
    1648             : 
    1649       78112 :       if (present(error)) then
    1650           0 :         error = actual_error
    1651       78112 :       else if (actual_error /= ELPA_OK) then
    1652           0 :         write(error_unit,'(a,i0,a)') "ELPA: Error converting value '", value, "' to a string for option '" // &
    1653           0 :                 name // "' and you did not check for errors: " // elpa_strerr(actual_error)
    1654             :       endif
    1655      156224 :     end function
    1656             : 
    1657             : 
    1658             :     !> \brief function to convert a string in its integer representation:
    1659             :     !> Parameters
    1660             :     !> \param   name        string: the key
    1661             :     !> \param   string      string: the string whose integer representation should be associated with the key
    1662             :     !> \param   error       integer, optional: error code, which can be queried with elpa_strerr()
    1663             :     !> \result  value       integer: the integer representation of the string
    1664           0 :     function elpa_int_string_to_value(name, string, error) result(value)
    1665             :       use elpa_generated_fortran_interfaces
    1666             :       use elpa_utilities, only : error_unit
    1667             :       implicit none
    1668             :       character(kind=c_char, len=*), intent(in)         :: name
    1669             :       character(kind=c_char, len=*), intent(in), target :: string
    1670             :       integer(kind=c_int), intent(out), optional        :: error
    1671             :       integer(kind=c_int)                               :: actual_error
    1672             : 
    1673             :       integer(kind=c_int)                               :: value
    1674             : 
    1675           0 :       actual_error = elpa_int_string_to_value_c(name // C_NULL_CHAR, string // C_NULL_CHAR, value)
    1676             : 
    1677           0 :       if (present(error)) then
    1678           0 :         error = actual_error
    1679           0 :       else if (actual_error /= ELPA_OK) then
    1680             :         write(error_unit,'(a)') "ELPA: Error converting string '" // string // "' to value for option '" // &
    1681           0 :                 name // "' and you did not check for errors: " // elpa_strerr(actual_error)
    1682             :       endif
    1683           0 :     end function
    1684             : 
    1685             : 
    1686             :     !> \brief function to get the number of possible choices for an option
    1687             :     !> Parameters
    1688             :     !> \param   option_name string:   the option
    1689             :     !> \result  number      integer:  the total number of possible values to be chosen
    1690        1920 :     function elpa_option_cardinality(option_name) result(number)
    1691             :       use elpa_generated_fortran_interfaces
    1692             :       character(kind=c_char, len=*), intent(in) :: option_name
    1693             :       integer                                   :: number
    1694        1920 :       number = elpa_option_cardinality_c(option_name // C_NULL_CHAR)
    1695        3840 :     end function
    1696             : 
    1697             : 
    1698             :     !> \brief function to enumerate an option
    1699             :     !> Parameters
    1700             :     !> \param   option_name string: the option
    1701             :     !> \param   i           integer
    1702             :     !> \result  option      integer
    1703       39360 :     function elpa_option_enumerate(option_name, i) result(option)
    1704             :       use elpa_generated_fortran_interfaces
    1705             :       character(kind=c_char, len=*), intent(in) :: option_name
    1706             :       integer, intent(in)                       :: i
    1707             :       integer                                   :: option
    1708       39360 :       option = elpa_option_enumerate_c(option_name // C_NULL_CHAR, i)
    1709       78720 :     end function
    1710             : 
    1711             : end module

Generated by: LCOV version 1.12