elpa_abstract_impl.F90 8.26 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
48
!
!    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.
!
#include "config-f90.h"
49
!> \brief Fortran module to provide an abstract definition of the implementation. Do not use directly. Use the module "elpa"
50
51
module elpa_abstract_impl
  use elpa_api
52
53
  use elpa_generated_fortran_interfaces

54
55
56
57
58
#ifdef HAVE_DETAILED_TIMINGS
  use ftimings
#else
  use timings_dummy
#endif
59
60


61
62
63
64
65
66
67
68
69
70
71
72
73
  implicit none

  ! The reason to have this additional layer is to allow for members (here the
  ! 'timer' object) that can be used internally but are not exposed to the
  ! public API. This cannot be done via 'private' members, as the scope of
  ! 'private' is per-file.
  !
  ! Thus, other sub-types or suplementary routines cannot use these members
  ! (unless they would all be implemented in one giant file)
  !
  type, abstract, extends(elpa_t) :: elpa_abstract_impl_t
#ifdef HAVE_DETAILED_TIMINGS
    type(timer_t) :: timer
74
    type(timer_t) :: autotune_timer
75
76
#else
    type(timer_dummy_t) :: timer
77
    type(timer_dummy_t) :: autotune_timer
78
#endif
79
    type(c_ptr)         :: index = C_NULL_PTR
Andreas Marek's avatar
Andreas Marek committed
80
    logical             :: eigenvalues_only
81
    contains
82
83
      procedure, public :: elpa_set_integer                      !< private methods to implement the setting of an integer/double key/value pair
      procedure, public :: elpa_set_double
84

85
86
      procedure, public :: elpa_get_integer                      !< private methods to implement the querry of an integer/double key/value pair
      procedure, public :: elpa_get_double
87

88
89
  end type

90
91
92
93
94
95
96
97
  contains

    !> \brief internal subroutine to set an integer key/value pair
    !> Parameters
    !> \param   self       the allocated ELPA object
    !> \param   name       string, the key
    !> \param   value      integer, the value to be set
    !> \result  error      integer, the error code
98
    subroutine elpa_set_integer(self, name, value, error)
99
      use iso_c_binding
100
      use elpa_utilities, only : error_unit
101
102
103
      class(elpa_abstract_impl_t)     :: self
      character(*), intent(in)        :: name
      integer(kind=c_int), intent(in) :: value
Andreas Marek's avatar
Andreas Marek committed
104
#ifdef USE_FORTRAN2008
105
      integer, optional               :: error
Andreas Marek's avatar
Andreas Marek committed
106
107
108
#else
      integer                         :: error
#endif
109
110
      integer                         :: actual_error

111
      actual_error = elpa_index_set_int_value_c(self%index, name // c_null_char, value)
112

Andreas Marek's avatar
Andreas Marek committed
113
#ifdef USE_FORTRAN2008
114
115
116
117
118
119
120
      if (present(error)) then
        error = actual_error

      else if (actual_error /= ELPA_OK) then
        write(error_unit,'(a,i0,a)') "ELPA: Error setting option '" // name // "' to value ", value, &
                " (got: " // elpa_strerr(actual_error) // ") and you did not check for errors!"
      end if
Andreas Marek's avatar
Andreas Marek committed
121
122
123
#else
      error = actual_error
#endif
124
125
126
127
128
129
130
131
    end subroutine

    !> \brief internal subroutine to get an integer key/value pair
    !> Parameters
    !> \param   self       the allocated ELPA object
    !> \param   name       string, the key
    !> \param   value      integer, the value of the key/vaue pair
    !> \param   error      integer, optional, to store an error code
132
    subroutine elpa_get_integer(self, name, value, error)
133
      use iso_c_binding
134
      use elpa_utilities, only : error_unit
135
136
137
      class(elpa_abstract_impl_t)    :: self
      character(*), intent(in)       :: name
      integer(kind=c_int)            :: value
Andreas Marek's avatar
Andreas Marek committed
138
#ifdef USE_FORTRAN2008
139
      integer, intent(out), optional :: error
Andreas Marek's avatar
Andreas Marek committed
140
141
142
#else
      integer, intent(out)           :: error
#endif
143
144
145
      integer                        :: actual_error

      value = elpa_index_get_int_value_c(self%index, name // c_null_char, actual_error)
Andreas Marek's avatar
Andreas Marek committed
146
147

#ifdef USE_FORTRAN2008
148
      if (present(error)) then
Andreas Marek's avatar
Andreas Marek committed
149
       error = actual_error
150
151
152
153
      else if (actual_error /= ELPA_OK) then
        write(error_unit,'(a)') "ELPA: Error getting option '" // name // "'" // &
                " (got: " // elpa_strerr(actual_error) // ") and you did not check for errors!"
      end if
Andreas Marek's avatar
Andreas Marek committed
154
155
156
#else
      error = actual_error
#endif
157
158
159
160
161
162
163
164
    end subroutine

    !> \brief internal subroutine to set a double key/value pair
    !> Parameters
    !> \param   self       the allocated ELPA object
    !> \param   name       string, the key
    !> \param   value      double, the value to be set
    !> \result  error      integer, the error code
165
    subroutine elpa_set_double(self, name, value, error)
166
      use iso_c_binding
167
      use elpa_utilities, only : error_unit
168
169
170
171
172
      class(elpa_abstract_impl_t)     :: self
      character(*), intent(in)        :: name
      real(kind=c_double), intent(in) :: value
      integer                         :: actual_error

Andreas Marek's avatar
Andreas Marek committed
173
174
175
176
177
#ifdef USE_FORTRAN2008
      integer,              optional  :: error
#else
      integer                         :: error
#endif
178
      actual_error = elpa_index_set_double_value_c(self%index, name // c_null_char, value)
179

Andreas Marek's avatar
Andreas Marek committed
180
#ifdef USE_FORTRAN2008
181
      if (present(error)) then
Andreas Marek's avatar
Andreas Marek committed
182
       error = actual_error
183
184
185
186
      else if (actual_error /= ELPA_OK) then
        write(error_unit,'(a,es12.5,a)') "ELPA: Error setting option '" // name // "' to value ", value, &
                " (got: " // elpa_strerr(actual_error) // ") and you did not check for errors!"
      end if
Andreas Marek's avatar
Andreas Marek committed
187
188
189
#else
      error = actual_error
#endif
190
191
192
193
194
195
196
197
    end subroutine

    !> \brief internal subroutine to get an double key/value pair
    !> Parameters
    !> \param   self       the allocated ELPA object
    !> \param   name       string, the key
    !> \param   value      double, the value of the key/vaue pair
    !> \param   error      integer, optional, to store an error code
198
    subroutine elpa_get_double(self, name, value, error)
199
      use iso_c_binding
200
      use elpa_utilities, only : error_unit
201
202
203
      class(elpa_abstract_impl_t)    :: self
      character(*), intent(in)       :: name
      real(kind=c_double)            :: value
Andreas Marek's avatar
Andreas Marek committed
204
#ifdef USE_FORTRAN2008
205
      integer, intent(out), optional :: error
Andreas Marek's avatar
Andreas Marek committed
206
207
208
#else
      integer, intent(out)           :: error
#endif
209
210
211
      integer                        :: actual_error

      value = elpa_index_get_double_value_c(self%index, name // c_null_char, actual_error)
Andreas Marek's avatar
Andreas Marek committed
212
#ifdef USE_FORTRAN2008
213
      if (present(error)) then
Andreas Marek's avatar
Andreas Marek committed
214
       error = actual_error
215
216
217
218
      else if (actual_error /= ELPA_OK) then
        write(error_unit,'(a)') "ELPA: Error getting option '" // name // "'" // &
                " (got: " // elpa_strerr(actual_error) // ") and you did not check for errors!"
      end if
Andreas Marek's avatar
Andreas Marek committed
219
220
221
#else
      error = actual_error
#endif
222
223
    end subroutine

224
end module