elpa_api.F90 71.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
!
!    Copyright 2017, L. Hüdepohl and A. Marek, MPCDF
!
!    This file is part of ELPA.
!
!    The ELPA library was originally created by the ELPA consortium,
!    consisting of the following organizations:
!
!    - Max Planck Computing and Data Facility (MPCDF), formerly known as
!      Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
!    - Bergische Universität Wuppertal, Lehrstuhl für angewandte
!      Informatik,
!    - Technische Universität München, Lehrstuhl für Informatik mit
!      Schwerpunkt Wissenschaftliches Rechnen ,
!    - Fritz-Haber-Institut, Berlin, Abt. Theorie,
!    - Max-Plack-Institut für Mathematik in den Naturwissenschaften,
!      Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
!      and
!    - IBM Deutschland GmbH
!
!    This particular source code file contains additions, changes and
!    enhancements authored by Intel Corporation which is not part of
!    the ELPA consortium.
!
!    More information can be found here:
!    http://elpa.mpcdf.mpg.de/
!
!    ELPA is free software: you can redistribute it and/or modify
!    it under the terms of the version 3 of the license of the
!    GNU Lesser General Public License as published by the Free
!    Software Foundation.
!
!    ELPA is distributed in the hope that it will be useful,
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU Lesser General Public License for more details.
!
!    You should have received a copy of the GNU Lesser General Public License
!    along with ELPA.  If not, see <http://www.gnu.org/licenses/>
!
!    ELPA reflects a substantial effort on the part of the original
!    ELPA consortium, and we ask you to respect the spirit of the
!    license that we chose: i.e., please contribute any changes you
!    may have back to the original ELPA library distribution, and keep
!    any derivatives of ELPA under the same license that we chose for
!    the original distribution, the GNU Lesser General Public License.
!
48 49
!> \brief Fortran module which provides the definition of the ELPA API. Do not use directly! Use the module "elpa"

Andreas Marek's avatar
Andreas Marek committed
50
#include "config-f90.h"
51

52 53 54 55 56
module elpa_api
  use elpa_constants
  use, intrinsic :: iso_c_binding
  implicit none

57
#include "src/elpa_generated_public_fortran_interfaces.h"
58

59 60 61 62
  integer, private, parameter :: earliest_api_version = EARLIEST_API_VERSION !< Definition of the earliest API version supported
                                                                             !< with the current release
  integer, private, parameter :: current_api_version  = CURRENT_API_VERSION  !< Definition of the current API version

Andreas Marek's avatar
Andreas Marek committed
63 64 65 66
  integer, private, parameter :: earliest_autotune_version = EARLIEST_AUTOTUNE_VERSION !< Definition of the earliest API version
                                                                                       !< which supports autotuning
  integer, private            :: api_version_set
  logical, private            :: initDone = .false.
67 68 69 70 71 72

  public :: elpa_t, &
      c_int, &
      c_double, c_double_complex, &
      c_float, c_float_complex

73
  !> \brief Abstract definition of the elpa_t type
74 75 76
  type, abstract :: elpa_t
    private

Andreas Marek's avatar
Andreas Marek committed
77

78
    !< these have to be public for proper bounds checking, sadly
79 80 81 82 83 84 85 86
    integer(kind=c_int), public, pointer :: na => NULL()
    integer(kind=c_int), public, pointer :: nev => NULL()
    integer(kind=c_int), public, pointer :: local_nrows => NULL()
    integer(kind=c_int), public, pointer :: local_ncols => NULL()
    integer(kind=c_int), public, pointer :: nblk => NULL()

    contains
      ! general
87 88
      procedure(elpa_setup_i),   deferred, public :: setup          !< method to setup an ELPA object
      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 93
          elpa_set_integer, &
          elpa_set_double
94 95 96 97

      generic, public :: get => &                                   !< export a method to get integer/double key/values
          elpa_get_integer, &
          elpa_get_double
98

99 100
      procedure(elpa_is_set_i),  deferred, public :: is_set         !< method to check whether key/value is set
      procedure(elpa_can_set_i), deferred, public :: can_set        !< method to check whether key/value can be set
101

102
      ! Timer
103 104 105 106
      procedure(elpa_get_time_i), deferred, public :: get_time        !< method to get the times from the timer object
      procedure(elpa_print_times_i), deferred, public :: print_times  !< method to print the timings tree
      procedure(elpa_timer_start_i), deferred, public :: timer_start  !< method to start a time measurement
      procedure(elpa_timer_stop_i), deferred, public :: timer_stop    !< method to stop a time measurement
107 108


109
      ! Actual math routines
Andreas Marek's avatar
Andreas Marek committed
110 111 112
      generic, public :: eigenvectors => &                          !< method eigenvectors for solving the full eigenvalue problem
          elpa_eigenvectors_d, &                                    !< the eigenvalues and (parts of) the eigenvectors are computed
          elpa_eigenvectors_f, &                                    !< for symmetric real valued / hermitian complex valued matrices
113 114
          elpa_eigenvectors_dc, &
          elpa_eigenvectors_fc
115

Andreas Marek's avatar
Andreas Marek committed
116 117 118 119 120 121
      generic, public :: eigenvalues => &                           !< method eigenvalues for solving the eigenvalue problem
          elpa_eigenvalues_d, &                                     !< only the eigenvalues are computed
          elpa_eigenvalues_f, &                                     !< for symmetric real valued / hermitian complex valued matrices
          elpa_eigenvalues_dc, &
          elpa_eigenvalues_fc

122
#if 0
Pavel Kus's avatar
Pavel Kus committed
123 124 125 126 127
      generic, public :: generalized_eigenvectors => &              !< method eigenvectors for solving the full generalized eigenvalue problem
          elpa_generalized_eigenvectors_d, &                        !< the eigenvalues and (parts of) the eigenvectors are computed
          elpa_generalized_eigenvectors_f, &                        !< for symmetric real valued / hermitian complex valued matrices
          elpa_generalized_eigenvectors_dc, &
          elpa_generalized_eigenvectors_fc
128
#endif
Pavel Kus's avatar
Pavel Kus committed
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 134
          elpa_hermitian_multiply_f, &
          elpa_hermitian_multiply_fc
135

136
      generic, public :: cholesky => &                              !< method for the cholesky factorisation of matrix a
137 138 139 140
          elpa_cholesky_d, &
          elpa_cholesky_f, &
          elpa_cholesky_dc, &
          elpa_cholesky_fc
141

Andreas Marek's avatar
Andreas Marek committed
142
      generic, public :: invert_triangular => &                     !< method to invert a upper triangular matrix a
143 144 145 146
          elpa_invert_trm_d, &
          elpa_invert_trm_f, &
          elpa_invert_trm_dc, &
          elpa_invert_trm_fc
147

148 149
      generic, public :: solve_tridiagonal => &                      !< method to solve the eigenvalue problem for a tridiagonal
          elpa_solve_tridiagonal_d, &                                !< matrix
150 151
          elpa_solve_tridiagonal_f

152
      ! Auto-tune
153 154 155
      procedure(elpa_autotune_setup_i), deferred, public :: autotune_setup       !< method to prepare the ELPA autotuning
      procedure(elpa_autotune_step_i), deferred, public :: autotune_step         !< method to do an autotuning step
      procedure(elpa_autotune_set_best_i), deferred, public :: autotune_set_best !< method to set the best options
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173

      !> \brief These method have to be public, in order to be overrideable in the extension types
      procedure(elpa_set_integer_i), deferred, public :: elpa_set_integer
      procedure(elpa_set_double_i),  deferred, public :: elpa_set_double

      procedure(elpa_get_integer_i), deferred, public :: elpa_get_integer
      procedure(elpa_get_double_i),  deferred, public :: elpa_get_double

      procedure(elpa_eigenvectors_d_i),    deferred, public :: elpa_eigenvectors_d
      procedure(elpa_eigenvectors_f_i),    deferred, public :: elpa_eigenvectors_f
      procedure(elpa_eigenvectors_dc_i), deferred, public :: elpa_eigenvectors_dc
      procedure(elpa_eigenvectors_fc_i), deferred, public :: elpa_eigenvectors_fc

      procedure(elpa_eigenvalues_d_i),    deferred, public :: elpa_eigenvalues_d
      procedure(elpa_eigenvalues_f_i),    deferred, public :: elpa_eigenvalues_f
      procedure(elpa_eigenvalues_dc_i), deferred, public :: elpa_eigenvalues_dc
      procedure(elpa_eigenvalues_fc_i), deferred, public :: elpa_eigenvalues_fc

174
#if 0
Pavel Kus's avatar
Pavel Kus committed
175 176 177 178
      procedure(elpa_generalized_eigenvectors_d_i),    deferred, public :: elpa_generalized_eigenvectors_d
      procedure(elpa_generalized_eigenvectors_f_i),    deferred, public :: elpa_generalized_eigenvectors_f
      procedure(elpa_generalized_eigenvectors_dc_i), deferred, public :: elpa_generalized_eigenvectors_dc
      procedure(elpa_generalized_eigenvectors_fc_i), deferred, public :: elpa_generalized_eigenvectors_fc
179
#endif
Pavel Kus's avatar
Pavel Kus committed
180

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
      procedure(elpa_hermitian_multiply_d_i),  deferred, public :: elpa_hermitian_multiply_d
      procedure(elpa_hermitian_multiply_f_i),  deferred, public :: elpa_hermitian_multiply_f
      procedure(elpa_hermitian_multiply_dc_i), deferred, public :: elpa_hermitian_multiply_dc
      procedure(elpa_hermitian_multiply_fc_i), deferred, public :: elpa_hermitian_multiply_fc

      procedure(elpa_cholesky_d_i),    deferred, public :: elpa_cholesky_d
      procedure(elpa_cholesky_f_i),    deferred, public :: elpa_cholesky_f
      procedure(elpa_cholesky_dc_i), deferred, public :: elpa_cholesky_dc
      procedure(elpa_cholesky_fc_i), deferred, public :: elpa_cholesky_fc

      procedure(elpa_invert_trm_d_i),    deferred, public :: elpa_invert_trm_d
      procedure(elpa_invert_trm_f_i),    deferred, public :: elpa_invert_trm_f
      procedure(elpa_invert_trm_dc_i), deferred, public :: elpa_invert_trm_dc
      procedure(elpa_invert_trm_fc_i), deferred, public :: elpa_invert_trm_fc

      procedure(elpa_solve_tridiagonal_d_i), deferred, public :: elpa_solve_tridiagonal_d
      procedure(elpa_solve_tridiagonal_f_i), deferred, public :: elpa_solve_tridiagonal_f
198 199 200
  end type elpa_t


201
  !> \brief Abstract definition of the elpa_autotune type
202 203 204 205 206 207 208
  type, abstract :: elpa_autotune_t
    private
    contains
      procedure(elpa_autotune_destroy_i), deferred, public :: destroy
      procedure(elpa_autotune_print_i), deferred, public :: print
  end type

209

210 211 212 213 214
  !> \brief definition of helper function to get C strlen
  !> Parameters
  !> \details
  !> \param   ptr         type(c_ptr) : pointer to string
  !> \result  size        integer(kind=c_size_t) : length of string
215 216 217
  interface
    pure function elpa_strlen_c(ptr) result(size) bind(c, name="strlen")
      use, intrinsic :: iso_c_binding
218
      implicit none
219 220 221 222 223
      type(c_ptr), intent(in), value :: ptr
      integer(kind=c_size_t) :: size
    end function
  end interface

224

225
  !> \brief abstract definition of the ELPA setup method
226 227 228 229
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \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 237 238
    end function
  end interface

239

240 241 242 243 244 245 246
  !> \brief abstract definition of the autotune setup method
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object, which should be tuned
  !> \param   level       integer: the level of "thoroughness" of the tuning steps
  !> \param   domain      integer: domain (real/complex) which should be tuned
  !> \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 250 251
      import elpa_t, elpa_autotune_t
      implicit none
      class(elpa_t), intent(inout), target :: self
252 253 254 255 256 257 258
      integer, intent(in)                  :: level, domain
      class(elpa_autotune_t), pointer      :: tune_state
#ifdef USE_FORTRAN2008
      integer , optional                   :: error
#else
      integer                              :: error
#endif
259 260 261 262
    end function
  end interface


263 264 265 266 267 268
  !> \brief abstract definition of the autotune step method
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object, which should be tuned
  !> \param   tune_state  class(elpa_autotune_t): the autotuning object
  !> \param   unfinished  logical: state whether tuning is unfinished or not
269 270 271 272 273 274 275 276 277 278
  abstract interface
    function elpa_autotune_step_i(self, tune_state) result(unfinished)
      import elpa_t, elpa_autotune_t
      implicit none
      class(elpa_t), intent(inout) :: self
      class(elpa_autotune_t), intent(inout), target :: tune_state
      logical :: unfinished
    end function
  end interface

279 280 281 282 283 284 285
  
  !> \brief abstract definition of the autotune set_best method
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object, which should be tuned
  !> \param   tune_state  class(elpa_autotune_t): the autotuning object
  !> Sets the best combination of ELPA options
286 287 288 289 290 291 292 293 294 295
  abstract interface
    subroutine elpa_autotune_set_best_i(self, tune_state)
      import elpa_t, elpa_autotune_t
      implicit none
      class(elpa_t), intent(inout) :: self
      class(elpa_autotune_t), intent(in), target :: tune_state
    end subroutine
  end interface


296 297 298 299 300 301 302
  !> \brief abstract definition of set method for integer values
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \param   name        string: the name of the key
  !> \param   value       integer : the value to set for the key
  !> \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 306
      use iso_c_binding
      import elpa_t
307
      implicit none
308 309 310
      class(elpa_t)                   :: self
      character(*), intent(in)        :: name
      integer(kind=c_int), intent(in) :: value
Andreas Marek's avatar
Andreas Marek committed
311
#ifdef USE_FORTRAN2008
312
      integer, optional               :: error
Andreas Marek's avatar
Andreas Marek committed
313 314 315
#else
      integer                         :: error
#endif
316 317 318
    end subroutine
  end interface

319

320 321 322 323 324
  !> \brief abstract definition of get method for integer values
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \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 330
      use iso_c_binding
      import elpa_t
331
      implicit none
332 333 334
      class(elpa_t)                  :: self
      character(*), intent(in)       :: name
      integer(kind=c_int)            :: value
Andreas Marek's avatar
Andreas Marek committed
335
#ifdef USE_FORTRAN2008
336
      integer, intent(out), optional :: error
Andreas Marek's avatar
Andreas Marek committed
337 338 339
#else
      integer, intent(out)           :: error
#endif
340
    end subroutine
341 342
  end interface

343

344 345 346 347 348 349 350
  !> \brief abstract definition of is_set method for integer values
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \param   name        string: the name of the key
  !> \result  state       integer : 1 is set, 0 if not, else a negativ error code
  !>                                                    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 356
      class(elpa_t)            :: self
      character(*), intent(in) :: name
357
      integer                  :: state
358 359 360
    end function
  end interface

361

362 363 364 365 366 367 368 369
  !> \brief abstract definition of can_set method for integer values
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \param   name        string: the name of the key
  !> \param   value       integer: the valye to associate with the key
  !> \result  state       integer : 1 is set, 0 if not, else a negativ error code
  !>                                                    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 375 376
      class(elpa_t)                   :: self
      character(*), intent(in)        :: name
      integer(kind=c_int), intent(in) :: value
377
      integer                         :: state
378
    end function
379 380
  end interface

381

382 383 384 385 386 387 388
  !> \brief abstract definition of set method for double values
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \param   name        string: the name of the key
  !? \param   value       double: the value to associate with the key
  !> \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 392
      use iso_c_binding
      import elpa_t
393
      implicit none
394 395 396
      class(elpa_t)                   :: self
      character(*), intent(in)        :: name
      real(kind=c_double), intent(in) :: value
Andreas Marek's avatar
Andreas Marek committed
397
#ifdef USE_FORTRAN2008
398
      integer, optional               :: error
Andreas Marek's avatar
Andreas Marek committed
399 400 401
#else
      integer                         :: error
#endif
402 403 404
    end subroutine
  end interface

405

406 407 408 409 410
  !> \brief abstract definition of get method for double values
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \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 416
      use iso_c_binding
      import elpa_t
417
      implicit none
418 419 420
      class(elpa_t)                  :: self
      character(*), intent(in)       :: name
      real(kind=c_double)            :: value
Andreas Marek's avatar
Andreas Marek committed
421
#ifdef USE_FORTRAN2008
422
      integer, intent(out), optional :: error
Andreas Marek's avatar
Andreas Marek committed
423 424 425
#else
      integer, intent(out)           :: error
#endif
426
    end subroutine
427 428
  end interface

429

430 431 432 433 434
  !> \brief abstract definition of associate method for integer pointers
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \param   name        string: the name of the key
435
  !> \result  value       integer, pointer: the value associated with the key
436 437 438 439
  abstract interface
    function elpa_associate_int_i(self, name) result(value)
      use iso_c_binding
      import elpa_t
440
      implicit none
441 442 443 444 445 446
      class(elpa_t)                  :: self
      character(*), intent(in)       :: name
      integer(kind=c_int), pointer   :: value
    end function
  end interface

447 448 449

  ! Timer routines

450 451 452 453 454 455
  !> \brief abstract definition of get_time method to querry the timer
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \param   name1..6    string: the name of the timer entry, supports up to 6 levels
  !> \result  s           double: the time for the entry name1..6
456 457 458
  abstract interface
    function elpa_get_time_i(self, name1, name2, name3, name4, name5, name6) result(s)
      import elpa_t, c_double
459
      implicit none
460 461 462 463 464 465 466
      class(elpa_t), intent(in) :: self
      ! this is clunky, but what can you do..
      character(len=*), intent(in), optional :: name1, name2, name3, name4, name5, name6
      real(kind=c_double) :: s
    end function
  end interface

467

468 469 470 471
  !> \brief abstract definition of print method for timer
  !> Parameters
  !> \details
  !> \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 478 479 480
      character(len=*), intent(in), optional :: name1, name2, name3, name4
    end subroutine
  end interface

481

482 483 484 485 486
  !> \brief abstract definition of the start method for timer
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \param   name        character(len=*) the name of the entry int the timer tree
487 488 489 490 491 492 493 494 495
  abstract interface
    subroutine elpa_timer_start_i(self, name)
      import elpa_t
      implicit none
      class(elpa_t), intent(inout) :: self
      character(len=*), intent(in) :: name
    end subroutine
  end interface

496

497 498 499 500 501
  !> \brief abstract definition of the stop method for timer
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t): the ELPA object
  !> \param   name        character(len=*) the name of the entry int the timer tree
502 503 504 505 506 507
  abstract interface
    subroutine elpa_timer_stop_i(self, name)
      import elpa_t
      implicit none
      class(elpa_t), intent(inout) :: self
      character(len=*), intent(in) :: name
508 509 510
    end subroutine
  end interface

511
  ! Actual math routines
512

513
  !> \brief abstract definition of interface to solve double real eigenvalue problem
514 515 516 517 518 519 520 521
  !>
  !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
522 523 524 525 526 527
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           double real matrix a: defines the problem to solve
  !> \param   ev          double real: on output stores the eigenvalues
  !> \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 532
      use iso_c_binding
      import elpa_t
533
      implicit none
534 535
      class(elpa_t)       :: self
#ifdef USE_ASSUMED_SIZE
Andreas Marek's avatar
Andreas Marek committed
536
      real(kind=c_double) :: a(self%local_nrows, *), q(self%local_nrows,*)
537 538 539 540 541
#else
      real(kind=c_double) :: a(self%local_nrows, self%local_ncols), q(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_double) :: ev(self%na)

Andreas Marek's avatar
Andreas Marek committed
542
#ifdef USE_FORTRAN2008
543
      integer, optional   :: error
Andreas Marek's avatar
Andreas Marek committed
544 545 546
#else
      integer             :: error
#endif
547 548 549
    end subroutine
  end interface

550

551
  !> \brief abstract definition of interface to solve single real eigenvalue problem
552 553 554 555 556 557 558 559
  !>
  !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
560 561 562 563 564 565
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           single real matrix a: defines the problem to solve
  !> \param   ev          single real: on output stores the eigenvalues
  !> \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 570
      use iso_c_binding
      import elpa_t
571
      implicit none
572 573 574 575 576 577 578
      class(elpa_t)       :: self
#ifdef USE_ASSUMED_SIZE
      real(kind=c_float)  :: a(self%local_nrows, *), q(self%local_nrows, *)
#else
      real(kind=c_float)  :: a(self%local_nrows, self%local_ncols), q(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_float)  :: ev(self%na)
Andreas Marek's avatar
Andreas Marek committed
579
#ifdef USE_FORTRAN2008
580
      integer, optional   :: error
Andreas Marek's avatar
Andreas Marek committed
581 582 583
#else
      integer             :: error
#endif
584 585 586
    end subroutine
  end interface

587

588
  !> \brief abstract definition of interface to solve double complex eigenvalue problem
589 590 591 592 593 594 595 596
  !>
  !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
597 598 599 600 601 602
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           double complex matrix a: defines the problem to solve
  !> \param   ev          double real: on output stores the eigenvalues
  !> \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 607
      use iso_c_binding
      import elpa_t
608
      implicit none
609 610 611 612 613 614 615 616
      class(elpa_t)                  :: self

#ifdef USE_ASSUMED_SIZE
      complex(kind=c_double_complex) :: a(self%local_nrows, *), q(self%local_nrows, *)
#else
      complex(kind=c_double_complex) :: a(self%local_nrows, self%local_ncols), q(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_double)            :: ev(self%na)
Andreas Marek's avatar
Andreas Marek committed
617
#ifdef USE_FORTRAN2008
618
      integer, optional              :: error
Andreas Marek's avatar
Andreas Marek committed
619 620 621
#else
      integer                        :: error
#endif
622 623 624
    end subroutine
  end interface

625

626
  !> \brief abstract definition of interface to solve single complex eigenvalue problem
627 628 629 630 631 632 633 634
  !>
  !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
635 636 637 638 639 640
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           single complex matrix a: defines the problem to solve
  !> \param   ev          single real: on output stores the eigenvalues
  !> \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 645
      use iso_c_binding
      import elpa_t
646
      implicit none
647 648 649 650 651 652 653
      class(elpa_t)                 :: self
#ifdef USE_ASSUMED_SIZE
      complex(kind=c_float_complex) :: a(self%local_nrows, *), q(self%local_nrows, *)
#else
      complex(kind=c_float_complex) :: a(self%local_nrows, self%local_ncols), q(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_float)            :: ev(self%na)
Andreas Marek's avatar
Andreas Marek committed
654
#ifdef USE_FORTRAN2008
655
      integer, optional             :: error
Andreas Marek's avatar
Andreas Marek committed
656 657 658
#else
      integer                       :: error
#endif
659 660 661
    end subroutine
  end interface

Andreas Marek's avatar
Andreas Marek committed
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689

  !> \brief abstract definition of interface to solve double real eigenvalue problem
  !>
  !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           double real matrix a: defines the problem to solve
  !> \param   ev          double real: on output stores the eigenvalues
  !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
  abstract interface
    subroutine elpa_eigenvalues_d_i(self, a, ev, error)
      use iso_c_binding
      import elpa_t
      implicit none
      class(elpa_t)       :: self
#ifdef USE_ASSUMED_SIZE
      real(kind=c_double) :: a(self%local_nrows, *)
#else
      real(kind=c_double) :: a(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_double) :: ev(self%na)
Andreas Marek's avatar
Andreas Marek committed
690
#ifdef USE_FORTRAN2008
Andreas Marek's avatar
Andreas Marek committed
691
      integer, optional   :: error
Andreas Marek's avatar
Andreas Marek committed
692 693 694
#else
      integer             :: error
#endif
Andreas Marek's avatar
Andreas Marek committed
695 696 697
    end subroutine
  end interface

698

Andreas Marek's avatar
Andreas Marek committed
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
  !> \brief abstract definition of interface to solve single real eigenvalue problem
  !>
  !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           single real matrix a: defines the problem to solve
  !> \param   ev          single real: on output stores the eigenvalues
  !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
  abstract interface
    subroutine elpa_eigenvalues_f_i(self, a, ev, error)
      use iso_c_binding
      import elpa_t
      implicit none
      class(elpa_t)       :: self
#ifdef USE_ASSUMED_SIZE
      real(kind=c_float)  :: a(self%local_nrows, *)
#else
      real(kind=c_float)  :: a(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_float)  :: ev(self%na)
Andreas Marek's avatar
Andreas Marek committed
726
#ifdef USE_FORTRAN2008
Andreas Marek's avatar
Andreas Marek committed
727
      integer, optional   :: error
Andreas Marek's avatar
Andreas Marek committed
728 729 730
#else
      integer             :: error
#endif
Andreas Marek's avatar
Andreas Marek committed
731 732 733
    end subroutine
  end interface

734

Andreas Marek's avatar
Andreas Marek committed
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762
  !> \brief abstract definition of interface to solve double complex eigenvalue problem
  !>
  !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           double complex matrix a: defines the problem to solve
  !> \param   ev          double real: on output stores the eigenvalues
  !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
  abstract interface
    subroutine elpa_eigenvalues_dc_i(self, a, ev, error)
      use iso_c_binding
      import elpa_t
      implicit none
      class(elpa_t)                  :: self

#ifdef USE_ASSUMED_SIZE
      complex(kind=c_double_complex) :: a(self%local_nrows, *)
#else
      complex(kind=c_double_complex) :: a(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_double)            :: ev(self%na)
Andreas Marek's avatar
Andreas Marek committed
763
#ifdef USE_FORTRAN2008
Andreas Marek's avatar
Andreas Marek committed
764
      integer, optional              :: error
Andreas Marek's avatar
Andreas Marek committed
765 766 767
#else
      integer                        :: error
#endif
Andreas Marek's avatar
Andreas Marek committed
768 769 770
    end subroutine
  end interface

771

Andreas Marek's avatar
Andreas Marek committed
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
  !> \brief abstract definition of interface to solve single complex eigenvalue problem
  !>
  !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           single complex matrix a: defines the problem to solve
  !> \param   ev          single real: on output stores the eigenvalues
  !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
  abstract interface
    subroutine elpa_eigenvalues_fc_i(self, a, ev, error)
      use iso_c_binding
      import elpa_t
      implicit none
      class(elpa_t)                 :: self
#ifdef USE_ASSUMED_SIZE
      complex(kind=c_float_complex) :: a(self%local_nrows, *)
#else
      complex(kind=c_float_complex) :: a(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_float)            :: ev(self%na)
Andreas Marek's avatar
Andreas Marek committed
799
#ifdef USE_FORTRAN2008
Andreas Marek's avatar
Andreas Marek committed
800
      integer, optional             :: error
Andreas Marek's avatar
Andreas Marek committed
801 802 803
#else
      integer                       :: error
#endif
Andreas Marek's avatar
Andreas Marek committed
804 805 806
    end subroutine
  end interface

807
#if 0
Pavel Kus's avatar
Pavel Kus committed
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955
  !> \brief abstract definition of interface to solve double real generalized eigenvalue problem
  !>
  !>  The dimensions of the matrix a and b (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           double real matrix a: defines the problem to solve
  !> \param   b           double real matrix b: defines the problem to solve
  !> \param   ev          double real: on output stores the eigenvalues
  !> \param   q           double real matrix q: on output stores the eigenvalues
  !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
  abstract interface
    subroutine elpa_generalized_eigenvectors_d_i(self, a, b, ev, q, sc_desc, error)
      use iso_c_binding
      use elpa_constants
      import elpa_t
      implicit none
      class(elpa_t)       :: self
#ifdef USE_ASSUMED_SIZE
      real(kind=c_double) :: a(self%local_nrows, *), b(self%local_nrows, *), q(self%local_nrows, *)
#else
      real(kind=c_double) :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols), &
                             q(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_double) :: ev(self%na)
      integer             :: sc_desc(SC_DESC_LEN)

      integer, optional   :: error
    end subroutine
  end interface

  !> \brief abstract definition of interface to solve single real generalized eigenvalue problem
  !>
  !>  The dimensions of the matrix a and b(locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           single real matrix a: defines the problem to solve
  !> \param   b           single real matrix b: defines the problem to solve
  !> \param   ev          single real: on output stores the eigenvalues
  !> \param   q           single real matrix q: on output stores the eigenvalues
  !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
  abstract interface
    subroutine elpa_generalized_eigenvectors_f_i(self, a, b, ev, q, sc_desc, error)
      use iso_c_binding
      use elpa_constants
      import elpa_t
      implicit none
      class(elpa_t)       :: self
#ifdef USE_ASSUMED_SIZE
      real(kind=c_float)  :: a(self%local_nrows, *), b(self%local_nrows, *), q(self%local_nrows, *)
#else
      real(kind=c_float)  :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols), &
                             q(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_float)  :: ev(self%na)
      integer             :: sc_desc(SC_DESC_LEN)

      integer, optional   :: error
    end subroutine
  end interface

  !> \brief abstract definition of interface to solve double complex generalized eigenvalue problem
  !>
  !>  The dimensions of the matrix a and b(locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           double complex matrix a: defines the problem to solve
  !> \param   b           double complex matrix b: defines the problem to solve
  !> \param   ev          double real: on output stores the eigenvalues
  !> \param   q           double complex matrix q: on output stores the eigenvalues
  !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
  abstract interface
    subroutine elpa_generalized_eigenvectors_dc_i(self, a, b, ev, q, sc_desc, error)
      use iso_c_binding
      use elpa_constants
      import elpa_t
      implicit none
      class(elpa_t)                  :: self

#ifdef USE_ASSUMED_SIZE
      complex(kind=c_double_complex) :: a(self%local_nrows, *), b(self%local_nrows, *), q(self%local_nrows, *)
#else
      complex(kind=c_double_complex) :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols), &
                                        q(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_double)            :: ev(self%na)
      integer                        :: sc_desc(SC_DESC_LEN)

      integer, optional              :: error
    end subroutine
  end interface

  !> \brief abstract definition of interface to solve single complex generalized eigenvalue problem
  !>
  !>  The dimensions of the matrix a (locally ditributed and global), the block-cyclic distribution
  !>  blocksize, the number of eigenvectors
  !>  to be computed and the MPI communicators are already known to the object and MUST be set BEFORE
  !>  with the class method "setup"
  !>
  !>  It is possible to change the behaviour of the method by setting tunable parameters with the
  !>  class method "set"
  !> Parameters
  !> \details
  !> \param   self        class(elpa_t), the ELPA object
  !> \param   a           single complex matrix a: defines the problem to solve
  !> \param   b           single complex matrix b: defines the problem to solve
  !> \param   ev          single real: on output stores the eigenvalues
  !> \param   q           single complex matrix q: on output stores the eigenvalues
  !> \result  error       integer, optional : error code, which can be queried with elpa_strerr
  abstract interface
    subroutine elpa_generalized_eigenvectors_fc_i(self, a, b, ev, q, sc_desc, error)
      use iso_c_binding
      use elpa_constants
      import elpa_t
      implicit none
      class(elpa_t)                 :: self
#ifdef USE_ASSUMED_SIZE
      complex(kind=c_float_complex) :: a(self%local_nrows, *), b(self%local_nrows, *), q(self%local_nrows, *)
#else
      complex(kind=c_float_complex) :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols), &
                                       q(self%local_nrows, self%local_ncols)
#endif
      real(kind=c_float)            :: ev(self%na)
      integer                       :: sc_desc(SC_DESC_LEN)

      integer, optional             :: error
    end subroutine
  end interface
956
#endif
Pavel Kus's avatar
Pavel Kus committed
957 958


Andreas Marek's avatar
Andreas Marek committed
959
  !> \brief abstract definition of interface to compute C : = A**T * B for double real matrices
960 961 962
  !>         where   A is a square matrix (self%a,self%na) which is optionally upper or lower triangular
  !>                 B is a (self%na,ncb) matrix
  !>                 C is a (self%na,ncb) matrix where optionally only the upper or lower
Andreas Marek's avatar
Andreas Marek committed
963 964 965 966
  !>                   triangle may be computed
  !>
  !> the MPI commicators are already known to the type. Thus the class method "setup" must be called
  !> BEFORE this method is used
967
  !> \details
Andreas Marek's avatar
Andreas Marek committed
968
  !>
969
  !> \param   self                class(elpa_t), the ELPA object
Andreas Marek's avatar
Andreas Marek committed
970 971 972 973 974 975 976 977 978 979 980 981 982 983
  !> \param  uplo_a               'U' if A is upper triangular
  !>                              'L' if A is lower triangular
  !>                              anything else if A is a full matrix
  !>                              Please note: This pertains to the original A (as set in the calling program)
  !>                                           whereas the transpose of A is used for calculations
  !>                              If uplo_a is 'U' or 'L', the other triangle is not used at all,
  !>                              i.e. it may contain arbitrary numbers
  !> \param uplo_c                'U' if only the upper diagonal part of C is needed
  !>                              'L' if only the upper diagonal part of C is needed
  !>                              anything else if the full matrix C is needed
  !>                              Please note: Even when uplo_c is 'U' or 'L', the other triangle may be
  !>                                            written to a certain extent, i.e. one shouldn't rely on the content there!
  !> \param ncb                   Number of columns  of global matrices B and C
  !> \param a                     matrix a
984 985
  !> \param self%local_nrows      number of rows of local (sub) matrix a, set with method set("local_nrows,value")
  !> \param self%local_ncols      number of columns of local (sub) matrix a, set with method set("local_ncols,value")
Andreas Marek's avatar
Andreas Marek committed
986 987 988 989 990 991 992 993
  !> \param b                     matrix b
  !> \param nrows_b               number of rows of local (sub) matrix b
  !> \param ncols_b               number of columns of local (sub) matrix b
  !> \param nblk                  blocksize of cyclic distribution, must be the same in both directions!
  !> \param c                     matrix c
  !> \param nrows_c               number of rows of local (sub) matrix c
  !> \param ncols_c               number of columns of local (sub) matrix c
  !> \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, &
Andreas Marek's avatar
Andreas Marek committed
996
                                          c, nrows_c, ncols_c, error)
997 998
      use iso_c_binding
      import elpa_t
999
      implicit none
1000 1001
      class(elpa_t)                   :: self
      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
Andreas Marek's avatar
Andreas Marek committed
1008
#ifdef USE_FORTRAN2008
1009
      integer, optional               :: error
Andreas Marek's avatar
Andreas Marek committed
1010 1011 1012
#else
      integer                         :: error
#endif
1013 1014 1015
    end subroutine
  end interface

1016

1017
  !> \brief abstract definition of interface to compute C : = A**T * B
1018 1019 1020
  !>         where   A is a square matrix (self%na,self%na) which is optionally upper or lower triangular
  !>                 B is a (self%na,ncb) matrix
  !>                 C is a (self%na,ncb) matrix where optionally only the upper or lower
Andreas Marek's avatar
Andreas Marek committed
1021 1022 1023 1024
  !>                   triangle may be computed
  !>
  !> the MPI commicators are already known to the type. Thus the class method "setup" must be called
  !> BEFORE this method is used
1025
  !> \details
Andreas Marek's avatar
Andreas Marek committed
1026
  !>
1027
  !> \param   self                class(elpa_t), the ELPA object
Andreas Marek's avatar
Andreas Marek committed
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041
  !> \param  uplo_a               'U' if A is upper triangular
  !>                              'L' if A is lower triangular
  !>                              anything else if A is a full matrix
  !>                              Please note: This pertains to the original A (as set in the calling program)
  !>                                           whereas the transpose of A is used for calculations
  !>                              If uplo_a is 'U' or 'L', the other triangle is not used at all,
  !>                              i.e. it may contain arbitrary numbers
  !> \param uplo_c                'U' if only the upper diagonal part of C is needed
  !>                              'L' if only the upper diagonal part of C is needed
  !>                              anything else if the full matrix C is needed
  !>                              Please note: Even when uplo_c is 'U' or 'L', the other triangle may be
  !>                                            written to a certain extent, i.e. one shouldn't rely on the content there!
  !> \param ncb                   Number of columns  of global matrices B and C
  !> \param a                     matrix a
1042 1043
  !> \param self%local_nrows      number of rows of local (sub) matrix a, set with method set("local_nrows",value)
  !> \param self%local_ncols      number of columns of local (sub) matrix a, set with method set("local_nrows",value)
Andreas Marek's avatar
Andreas Marek committed
1044 1045 1046 1047 1048 1049 1050 1051
  !> \param b                     matrix b
  !> \param nrows_b               number of rows of local (sub) matrix b
  !> \param ncols_b               number of columns of local (sub) matrix b
  !> \param nblk                  blocksize of cyclic distribution, must be the same in both directions!
  !> \param c                     matrix c
  !> \param nrows_c               number of rows of local (sub) matrix c
  !> \param ncols_c               number of columns of local (sub) matrix c
  !> \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, &
Andreas Marek's avatar
Andreas Marek committed
1054
                                          c, nrows_c, ncols_c, error)
1055 1056
      use iso_c_binding
      import elpa_t
1057
      implicit none
1058 1059
      class(elpa_t)                   :: self
      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
Andreas Marek's avatar
Andreas Marek committed
1066
#ifdef USE_FORTRAN2008
1067
      integer, optional               :: error
Andreas Marek's avatar
Andreas Marek committed
1068 1069 1070
#else
      integer                         :: error
#endif
1071 1072 1073
    end subroutine
  end interface

1074

1075
  !> \brief abstract definition of interface to compute C : = A**H * B
1076 1077 1078
  !>         where   A is a square matrix (self%na,self%a) which is optionally upper or lower triangular
  !>                 B is a (self%na,ncb) matrix
  !>                 C is a (self%na,ncb) matrix where optionally only the upper or lower
Andreas Marek's avatar
Andreas Marek committed
1079 1080 1081 1082
  !>                   triangle may be computed
  !>
  !> the MPI commicators are already known to the type. Thus the class method "setup" must be called
  !> BEFORE this method is used
1083
  !> \details
Andreas Marek's avatar
Andreas Marek committed
1084
  !>
1085
  !> \param   self                class(elpa_t), the ELPA object
Andreas Marek's avatar
Andreas Marek committed
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
  !> \param  uplo_a               'U' if A is upper triangular
  !>                              'L' if A is lower triangular
  !>                              anything else if A is a full matrix
  !>                              Please note: This pertains to the original A (as set in the calling program)
  !>                                           whereas the transpose of A is used for calculations
  !>                              If uplo_a is 'U' or 'L', the other triangle is not used at all,
  !>                              i.e. it may contain arbitrary numbers
  !> \param uplo_c                'U' if only the upper diagonal part of C is needed
  !>                              'L' if only the upper diagonal part of C is needed
  !>                              anything else if the full matrix C is needed
  !>                              Please note: Even when uplo_c is 'U' or 'L', the other triangle may be
  !>                                            written to a certain extent, i.e. one shouldn't rely on the content there!
  !> \param ncb                   Number of columns  of global matrices B and C
  !> \param a                     matrix a
1100 1101
  !> \param self%local_nrows      number of rows of local (sub) matrix a, set with the method set("local_nrows",value)
  !> \param self%local_ncols      number of columns of local (sub) matrix a, set with the method set("local_ncols",value)
Andreas Marek's avatar
Andreas Marek committed
1102 1103 1104 1105 1106 1107 1108 1109
  !> \param b                     matrix b
  !> \param nrows_b               number of rows of local (sub) matrix b
  !> \param ncols_b               number of columns of local (sub) matrix b
  !> \param nblk                  blocksize of cyclic distribution, must be the same in both directions!
  !> \param c                     matrix c
  !> \param nrows_c               number of rows of local (sub) matrix c
  !> \param ncols_c               number of columns of local (sub) matrix c
  !> \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, &
Andreas Marek's avatar
Andreas Marek committed
1112
                                          c, nrows_c, ncols_c, error)
1113 1114
      use iso_c_binding
      import elpa_t
1115
      implicit none
1116 1117
      class(elpa_t)                   :: self
      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
Andreas Marek's avatar
Andreas Marek committed
1124
#ifdef USE_FORTRAN2008
1125
      integer, optional               :: error
Andreas Marek's avatar
Andreas Marek committed
1126 1127 1128
#else
      integer                         :: error
#endif
1129 1130 1131
    end subroutine
  end interface

Lorenz Huedepohl's avatar <