Eigenvalue SoLvers for Petaflop-Applications (ELPA) 2024.05.001
Loading...
Searching...
No Matches
elpa_impl_math_generalized_template.F90
Go to the documentation of this file.
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!
82 subroutine elpa_generalized_eigenvectors_&
83 &elpa_impl_suffix&
84 & (self, a, b, ev, q, is_already_decomposed, error)
85 use elpa2_impl
86 use elpa1_impl
87 use elpa_utilities, only : error_unit
88 use, intrinsic :: iso_c_binding
89 class(elpa_impl_t) :: self
90
91#ifdef USE_ASSUMED_SIZE
92 math_datatype(kind=c_datatype_kind) :: a(self%local_nrows, *), b(self%local_nrows, *), q(self%local_nrows, *)
93#else
94 math_datatype(kind=c_datatype_kind) :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols), &
95 q(self%local_nrows, self%local_ncols)
96#endif
97 real(kind=c_real_datatype) :: ev(self%na)
98 logical :: is_already_decomposed
99
100 integer, optional :: error
101 integer :: error_l
102 integer(kind=c_int) :: solver
103 logical :: success_l
104
105 error_l = -10
106 success_l = .false.
107#if defined(INCLUDE_ROUTINES)
108 call self%elpa_transform_generalized_&
109 &elpa_impl_suffix&
110 & (a, b, is_already_decomposed, error_l)
111#endif
112 if (present(error)) then
113 error = error_l
114 else if (error_l .ne. elpa_ok) then
115 write(error_unit,'(a)') "ELPA: Error in transform_generalized() and you did not check for errors!"
116 endif
117
118 call self%get("solver", solver,error_l)
119 if (solver .eq. elpa_solver_1stage) then
120#if defined(INCLUDE_ROUTINES)
121 success_l = elpa_solve_evp_&
122 &math_datatype&
123 &_1stage_a_h_a_&
124 &precision&
125 &_impl(self, a, ev, q)
126#endif
127 else if (solver .eq. elpa_solver_2stage) then
128#if defined(INCLUDE_ROUTINES)
129 success_l = elpa_solve_evp_&
130 &math_datatype&
131 &_2stage_a_h_a_&
132 &precision&
133 &_impl(self, a, ev, q)
134#endif
135 else
136 write(error_unit,'(a)') "Unknown solver: Aborting!"
137#ifdef USE_FORTRAN2008
138 if (present(error)) then
139 error = elpa_error
140 return
141 else
142 return
143 endif
144#else
145 error = elpa_error
146 return
147#endif
148 endif
149
150 if (present(error)) then
151 if (success_l) then
152 error = elpa_ok
153 else
154 error = elpa_error
155 endif
156 else if (.not. success_l) then
157 write(error_unit,'(a)') "ELPA: Error in solve() and you did not check for errors!"
158 endif
159
160#if defined(INCLUDE_ROUTINES)
161 call self%elpa_transform_back_generalized_&
162 &elpa_impl_suffix&
163 & (b, q, error_l)
164#endif
165 if (present(error)) then
166 error = error_l
167 else if (error_l .ne. elpa_ok) then
168 write(error_unit,'(a)') "ELPA: Error in transform_back_generalized() and you did not check for errors!"
169 endif
170 end subroutine
171
172 !c> // /src/elpa_impl_math_generalized_template.F90
173
174#ifdef REALCASE
175#ifdef DOUBLE_PRECISION_REAL
176 !c> void elpa_generalized_eigenvectors_d(elpa_t handle, double *a, double *b, double *ev, double *q,
177 !c> int is_already_decomposed, int *error);
178#endif
179#ifdef SINGLE_PRECISION_REAL
180 !c> void elpa_generalized_eigenvectors_f(elpa_t handle, float *a, float *b, float *ev, float *q,
181 !c> int is_already_decomposed, int *error);
182#endif
183#endif
184#ifdef COMPLEXCASE
185#ifdef DOUBLE_PRECISION_COMPLEX
186 !c> void elpa_generalized_eigenvectors_dc(elpa_t handle, double_complex *a, double_complex *b, double *ev, double_complex *q,
187 !c> int is_already_decomposed, int *error);
188#endif
189#ifdef SINGLE_PRECISION_COMPLEX
190 !c> void elpa_generalized_eigenvectors_fc(elpa_t handle, float_complex *a, float_complex *b, float *ev, float_complex *q,
191 !c> int is_already_decomposed, int *error);
192#endif
193#endif
194 subroutine elpa_generalized_eigenvectors_&
195 &elpa_impl_suffix&
196 &_c(handle, a_p, b_p, ev_p, q_p, is_already_decomposed, error) &
197#ifdef REALCASE
198#ifdef DOUBLE_PRECISION_REAL
199 bind(C, name="elpa_generalized_eigenvectors_d")
200#endif
201#ifdef SINGLE_PRECISION_REAL
202 bind(C, name="elpa_generalized_eigenvectors_f")
203#endif
204#endif
205#ifdef COMPLEXCASE
206#ifdef DOUBLE_PRECISION_COMPLEX
207 bind(C, name="elpa_generalized_eigenvectors_dc")
208#endif
209#ifdef SINGLE_PRECISION_COMPLEX
210 bind(C, name="elpa_generalized_eigenvectors_fc")
211#endif
212#endif
213 type(c_ptr), intent(in), value :: handle, a_p, b_p, ev_p, q_p
214 integer(kind=c_int), intent(in), value :: is_already_decomposed
215#ifdef USE_FORTRAN2008
216 integer(kind=c_int), optional, intent(in) :: error
217#else
218 integer(kind=c_int), intent(in) :: error
219#endif
220 math_datatype(kind=c_datatype_kind), pointer :: a(:, :), b(:, :), q(:, :)
221 real(kind=c_real_datatype), pointer :: ev(:)
222 logical :: is_already_decomposed_fortran
223 type(elpa_impl_t), pointer :: self
224
225 call c_f_pointer(handle, self)
226 call c_f_pointer(a_p, a, [self%local_nrows, self%local_ncols])
227 call c_f_pointer(b_p, b, [self%local_nrows, self%local_ncols])
228 call c_f_pointer(ev_p, ev, [self%na])
229 call c_f_pointer(q_p, q, [self%local_nrows, self%local_ncols])
230 if(is_already_decomposed .eq. 0) then
231 is_already_decomposed_fortran = .false.
232 else
233 is_already_decomposed_fortran = .true.
234 end if
235
236 call elpa_generalized_eigenvectors_&
237 &elpa_impl_suffix&
238 & (self, a, b, ev, q, is_already_decomposed_fortran, error)
239 end subroutine
240
241
242
272 subroutine elpa_generalized_eigenvalues_&
273 &elpa_impl_suffix&
274 & (self, a, b, ev, is_already_decomposed, error)
275 use elpa2_impl
276 use elpa1_impl
277 use elpa_utilities, only : error_unit
278 use, intrinsic :: iso_c_binding
279 class(elpa_impl_t) :: self
280
281#ifdef USE_ASSUMED_SIZE
282 math_datatype(kind=c_datatype_kind) :: a(self%local_nrows, *), b(self%local_nrows, *)
283#else
284 math_datatype(kind=c_datatype_kind) :: a(self%local_nrows, self%local_ncols), b(self%local_nrows, self%local_ncols)
285#endif
286 real(kind=c_real_datatype) :: ev(self%na)
287 logical :: is_already_decomposed
288
289 integer, optional :: error
290 integer :: error_l
291 integer(kind=c_int) :: solver
292 logical :: success_l
293
294 error_l = -10
295 success_l = .false.
296#if defined(INCLUDE_ROUTINES)
297 call self%elpa_transform_generalized_&
298 &elpa_impl_suffix&
299 & (a, b, is_already_decomposed, error_l)
300#endif
301 if (present(error)) then
302 error = error_l
303 else if (error_l .ne. elpa_ok) then
304 write(error_unit,'(a)') "ELPA: Error in transform_generalized() and you did not check for errors!"
305 endif
306
307 call self%get("solver", solver,error_l)
308 if (solver .eq. elpa_solver_1stage) then
309#if defined(INCLUDE_ROUTINES)
310 success_l = elpa_solve_evp_&
311 &math_datatype&
312 &_1stage_a_h_a_&
313 &precision&
314 &_impl(self, a, ev)
315#endif
316 else if (solver .eq. elpa_solver_2stage) then
317#if defined(INCLUDE_ROUTINES)
318 success_l = elpa_solve_evp_&
319 &math_datatype&
320 &_2stage_a_h_a_&
321 &precision&
322 &_impl(self, a, ev)
323#endif
324 else
325 write(error_unit,'(a)') "Unknown solver: Aborting!"
326#ifdef USE_FORTRAN2008
327 if (present(error)) then
328 error = elpa_error
329 return
330 else
331 return
332 endif
333#else
334 error = elpa_error
335 return
336#endif
337 endif
338
339 if (present(error)) then
340 if (success_l) then
341 error = elpa_ok
342 else
343 error = elpa_error
344 endif
345 else if (.not. success_l) then
346 write(error_unit,'(a)') "ELPA: Error in solve() and you did not check for errors!"
347 endif
348
349 end subroutine
350
351#ifdef REALCASE
352#ifdef DOUBLE_PRECISION_REAL
353 !c> void elpa_generalized_eigenvalues_d(elpa_t handle, double *a, double *b, double *ev,
354 !c> int is_already_decomposed, int *error);
355#endif
356#ifdef SINGLE_PRECISION_REAL
357 !c> void elpa_generalized_eigenvalues_f(elpa_t handle, float *a, float *b, float *ev,
358 !c> int is_already_decomposed, int *error);
359#endif
360#endif
361#ifdef COMPLEXCASE
362#ifdef DOUBLE_PRECISION_COMPLEX
363 !c> void elpa_generalized_eigenvalues_dc(elpa_t handle, double_complex *a, double_complex *b, double *ev,
364 !c> int is_already_decomposed, int *error);
365#endif
366#ifdef SINGLE_PRECISION_COMPLEX
367 !c> void elpa_generalized_eigenvalues_fc(elpa_t handle, float_complex *a, float_complex *b, float *ev,
368 !c> int is_already_decomposed, int *error);
369#endif
370#endif
371 subroutine elpa_generalized_eigenvalues_&
372 &elpa_impl_suffix&
373 &_c(handle, a_p, b_p, ev_p, is_already_decomposed, error) &
374#ifdef REALCASE
375#ifdef DOUBLE_PRECISION_REAL
376 bind(C, name="elpa_generalized_eigenvalues_d")
377#endif
378#ifdef SINGLE_PRECISION_REAL
379 bind(C, name="elpa_generalized_eigenvalues_f")
380#endif
381#endif
382#ifdef COMPLEXCASE
383#ifdef DOUBLE_PRECISION_COMPLEX
384 bind(C, name="elpa_generalized_eigenvalues_dc")
385#endif
386#ifdef SINGLE_PRECISION_COMPLEX
387 bind(C, name="elpa_generalized_eigenvalues_fc")
388#endif
389#endif
390 type(c_ptr), intent(in), value :: handle, a_p, b_p, ev_p
391 integer(kind=c_int), intent(in), value :: is_already_decomposed
392#ifdef USE_FORTRAN2008
393 integer(kind=c_int), optional, intent(in) :: error
394#else
395 integer(kind=c_int), intent(in) :: error
396#endif
397
398 math_datatype(kind=c_datatype_kind), pointer :: a(:, :), b(:, :)
399 real(kind=c_real_datatype), pointer :: ev(:)
400 logical :: is_already_decomposed_fortran
401 type(elpa_impl_t), pointer :: self
402
403 call c_f_pointer(handle, self)
404 call c_f_pointer(a_p, a, [self%local_nrows, self%local_ncols])
405 call c_f_pointer(b_p, b, [self%local_nrows, self%local_ncols])
406 call c_f_pointer(ev_p, ev, [self%na])
407 if(is_already_decomposed .eq. 0) then
408 is_already_decomposed_fortran = .false.
409 else
410 is_already_decomposed_fortran = .true.
411 end if
412
413 call elpa_generalized_eigenvalues_&
414 &elpa_impl_suffix&
415 & (self, a, b, ev, is_already_decomposed_fortran, error)
416 end subroutine
417