Branch data Line data Source code
1 : : !{\src2tex{textfont=tt}}
2 : : !!****f* m_abi_linalg/abi_xheev
3 : : !! NAME
4 : : !! abi_xheev
5 : : !!
6 : : !! FUNCTION
7 : : !! abi_xheev is the generic function that compute
8 : : !! all eigenvalues and, optionally, eigenvectors of a
9 : : !! symmetric or hermitian matrix A.
10 : : !!
11 : : !! COPYRIGHT
12 : : !! Copyright (C) 2001-2026 ABINIT group (LNguyen,FDahm,MT)
13 : : !! This file is distributed under the terms of the
14 : : !! GNU General Public License, see ~abinit/COPYING
15 : : !! or http://www.gnu.org/copyleft/gpl.txt .
16 : : !!
17 : : !! SOURCE
18 : :
19 : : !!***
20 : :
21 : : !!****f* m_abi_linalg/abi_dheev
22 : : !! NAME
23 : : !! abi_dheev
24 : : !!
25 : : !! FUNCTION
26 : : !!
27 : : !! INPUTS
28 : : !!
29 : : !! SOURCE
30 : : !!
31 : 34551 : subroutine abi_dheev(jobz,uplo,n,a,lda,w,&
32 : : & x_cplx,istwf_k,timopt,tim_xeigen,&
33 : : & use_gpu_elpa,use_gpu_magma,use_slk)
34 : :
35 : : !Arguments ------------------------------------
36 : : character(len=1), intent(in) :: jobz
37 : : character(len=1), intent(in) :: uplo
38 : : integer, intent(in) :: n,lda
39 : : real(dp), intent(inout) :: a(n,*) ! FIXME should be cplex * lda
40 : : real(dp), intent(out) :: w(n)
41 : : integer, optional, intent(in) :: istwf_k
42 : : integer, optional, intent(in) :: x_cplx
43 : : integer, optional, intent(in) :: timopt,tim_xeigen
44 : : integer, optional, intent(in) :: use_gpu_elpa,use_gpu_magma,use_slk
45 : :
46 : : !Local variables-------------------------------
47 : : integer :: cplx_,istwf_k_,use_gpu_elpa_,use_gpu_magma_,use_slk_
48 : : integer :: info
49 : : real(dp) :: tsec(2)
50 : :
51 : : ! *********************************************************************
52 : :
53 [ - + ]: 34551 : ABI_CHECK(lapack_full_storage,"BUG(1) in abi_dheev (storage)!")
54 [ - + ]: 34551 : ABI_CHECK(lapack_double_precision,"BUG(2) in abi_dheev (precision)!")
55 [ - + ]: 34551 : ABI_CHECK(n<=eigen_d_maxsize,"BUG(3) in abi_dheev (maxsize)!")
56 : :
57 [ + - ]: 34551 : if (present(tim_xeigen).and.present(timopt)) then
58 [ - + ]: 34551 : if(abs(timopt)==3) call timab(tim_xeigen,1,tsec)
59 : : end if
60 : :
61 [ + - ]: 34551 : cplx_=1 ; if(present(x_cplx)) cplx_ = x_cplx
62 [ + - ]: 34551 : use_gpu_magma_=0;if (present(use_gpu_magma)) use_gpu_magma_=use_gpu_magma
63 : 34551 : istwf_k_=1;if (present(istwf_k)) istwf_k_=istwf_k
64 [ + - ]: 34551 : use_slk_ = 0; if(present(use_slk)) use_slk_ = use_slk
65 : 34551 : use_gpu_elpa_=0
66 : : #ifdef HAVE_LINALG_ELPA
67 : : if (present(use_gpu_elpa)) use_gpu_elpa_=use_gpu_elpa
68 : : #endif
69 : :
70 : : !===== MAGMA
71 [ - + - - ]: 34551 : if (ABI_LINALG_MAGMA_ISON.and.use_gpu_magma_==1) then
72 : : #if defined HAVE_LINALG_MAGMA
73 : : ABI_CHECK((lapack_divide_conquer),"BUG(4) in abi_dheev (d&c)!")
74 : : if (cplx_ == 2) then
75 : : call magmaf_zheevd(jobz,uplo,n,a,lda,w,eigen_z_work,eigen_z_lwork, &
76 : : & eigen_z_rwork,eigen_z_lrwork,eigen_iwork,eigen_liwork,info)
77 : : else
78 : : call magmaf_dsyevd(jobz,uplo,n,a,lda,w,eigen_d_work,eigen_d_lwork,&
79 : : & eigen_iwork,eigen_liwork,info)
80 : : endif
81 : : #endif
82 : :
83 : : !===== SCALAPACK
84 [ - + - - : 34551 : else if (ABI_LINALG_SCALAPACK_ISON.and.use_slk_==1.and.n>slk_minsize) then
- - ]
85 : : #if defined HAVE_LINALG_SCALAPACK
86 : : ABI_CHECK(present(x_cplx),"BUG(5) in abi_dheev (x_cplx)!")
87 : : call compute_eigen1(slk_communicator,slk_processor,cplx_,n,n,a,w,istwf_k_,&
88 : : & use_gpu_elpa=use_gpu_elpa_)
89 : : info = 0 ! This is to avoid unwanted warning but it's not clean
90 : : #endif
91 : :
92 : : !===== PLASMA
93 : : !FDahm & LNGuyen (November 2012) :
94 : : ! In Plasma v 2.4.6, eigen routines support only
95 : : ! the eigenvalues computation (jobz=N) and not the
96 : : ! full eigenvectors bases determination (jobz=V)
97 [ - + - - ]: 34551 : else if (ABI_LINALG_PLASMA_ISON.and.LSAME(jobz,'N')) then
98 : : #if defined HAVE_LINALG_PLASMA
99 : : jobz_plasma_a = jobz_plasma(jobz)
100 : : if (cplx_ == 2) then
101 : : call PLASMA_Alloc_Workspace_zheev(n,n,plasma_work,info)
102 : : info = PLASMA_zheev_c(jobz_plasma(jobz),uplo_plasma(uplo),n,c_loc(a),lda,c_loc(w),&
103 : : & plasma_work,c_loc(eigen_z_work),n)
104 : : else
105 : : call PLASMA_Alloc_Workspace_dsyev(n,n,plasma_work,info)
106 : : info = PLASMA_dsyev_c(jobz_plasma(jobz),uplo_plasma(uplo),n,c_loc(a),lda,c_loc(w),&
107 : : & plasma_work,c_loc(eigen_d_work),n)
108 : : endif
109 : : call PLASMA_Dealloc_handle(plasma_work,info)
110 : : #endif
111 : :
112 : : !===== LAPACK
113 : : else
114 [ + + ]: 34551 : if (cplx_ == 2) then
115 : 32472 : call zheev(jobz,uplo,n,a,lda,w,eigen_z_work,eigen_z_lwork,eigen_z_rwork,info)
116 : : else
117 : 2079 : call dsyev(jobz,uplo,n,a,lda,w,eigen_d_work,eigen_d_lwork,info)
118 : : endif
119 : : end if
120 : :
121 [ + - ]: 34551 : if (present(tim_xeigen).and.present(timopt)) then
122 [ - + ]: 34551 : if(abs(timopt)==3) call timab(tim_xeigen,2,tsec)
123 : : end if
124 : :
125 [ - + ]: 34551 : ABI_CHECK(info==0,"abi_dheev returned info!=0!")
126 : :
127 : : #ifndef HAVE_LINALG_ELPA
128 : : ABI_UNUSED(use_gpu_elpa)
129 : : #endif
130 : :
131 : 34551 : end subroutine abi_dheev
132 : : !!***
133 : :
134 : : !----------------------------------------------------------------------
135 : :
136 : : !!****f* m_abi_linalg/abi_cheev
137 : : !! NAME
138 : : !! abi_cheev
139 : : !!
140 : : !! FUNCTION
141 : : !!
142 : : !! INPUTS
143 : : !!
144 : : !! SOURCE
145 : :
146 : 0 : subroutine abi_cheev(jobz,uplo,n,a,lda,w)
147 : :
148 : : !Arguments ------------------------------------
149 : : character(len=1), intent(in) :: jobz
150 : : character(len=1), intent(in) :: uplo
151 : : integer, intent(in) :: n,lda
152 : : complex(sp), intent(inout) :: a(lda,*)
153 : : real(sp), intent(out) :: w(n)
154 : :
155 : : !Local variables-------------------------------
156 : : integer :: info,lwork
157 : : real(sp),pointer :: rwork(:)
158 : : complex(sp),pointer :: work(:)
159 : : ! *********************************************************************
160 : :
161 [ # # ]: 0 : ABI_CHECK(lapack_full_storage,"BUG(1) in abi_cheev (storage)!")
162 [ # # ]: 0 : ABI_CHECK(lapack_single_precision,"BUG(2) in abi_cheev (precision)!")
163 [ # # ]: 0 : ABI_CHECK(n<=eigen_c_maxsize,"BUG(3) in abi_cheev (maxsize)!")
164 : :
165 : 0 : work => eigen_c_work ; rwork => eigen_c_rwork
166 : 0 : lwork=eigen_c_lwork
167 : :
168 : : !===== PLASMA
169 : : !FDahm & LNGuyen (November 2012) :
170 : : ! In Plasma v 2.4.6, eigen routines support only
171 : : ! the eigenvalues computation (jobz=N) and not the
172 : : ! full eigenvectors bases determination (jobz=V)
173 [ # # # # ]: 0 : if (ABI_LINALG_PLASMA_ISON.and.LSAME(jobz,'N')) then
174 : : #if defined HAVE_LINALG_PLASMA
175 : : if (eigen_c_lwork==0) then
176 : : ABI_MALLOC(work,(n**2))
177 : : end if
178 : : call PLASMA_Alloc_Workspace_cheev(n,n,plasma_work,info)
179 : : info = PLASMA_cheev_c(jobz_plasma(jobz),uplo_plasma(uplo),n,c_loc(a),lda,c_loc(w),&
180 : : & plasma_work,c_loc(work),n)
181 : : call PLASMA_Dealloc_handle(plasma_work,info)
182 : : if (eigen_c_lwork==0) then
183 : : ABI_FREE(work)
184 : : end if
185 : : #endif
186 : :
187 : : !===== LAPACK
188 : : else
189 [ # # ]: 0 : if (eigen_c_lwork==0) then
190 : 0 : lwork=2*n-1
191 [ # # # # : 0 : ABI_MALLOC(work,(lwork))
# # # # #
# # # ]
192 : : end if
193 [ # # ]: 0 : if (eigen_c_lrwork==0) then
194 [ # # # # : 0 : ABI_MALLOC(rwork,(3*n-2))
# # # # #
# # # #
# ]
195 : : end if
196 [ # # # # ]: 0 : call cheev(jobz,uplo,n,a,lda,w,work,lwork,rwork,info)
197 [ # # ]: 0 : if (eigen_c_lwork==0) then
198 [ # # ]: 0 : ABI_FREE(work)
199 : : end if
200 [ # # ]: 0 : if (eigen_c_lrwork==0) then
201 [ # # ]: 0 : ABI_FREE(rwork)
202 : : end if
203 : : end if
204 : :
205 [ # # ]: 0 : ABI_CHECK(info==0,"abi_cheev returned info!=!0")
206 : :
207 : 0 : end subroutine abi_cheev
208 : : !!***
209 : :
210 : : !----------------------------------------------------------------------
211 : :
212 : : !!****f* m_abi_linalg/abi_zheev
213 : : !! NAME
214 : : !! abi_zheev
215 : : !!
216 : : !! FUNCTION
217 : : !!
218 : : !! INPUTS
219 : : !!
220 : : !! SOURCE
221 : :
222 : 0 : subroutine abi_zheev(jobz,uplo,n,a,lda,w)
223 : :
224 : : !Arguments ------------------------------------
225 : : character(len=1), intent(in) :: jobz
226 : : character(len=1), intent(in) :: uplo
227 : : integer, intent(in) :: n,lda
228 : : complex(dp), intent(inout) :: a(lda,*)
229 : : real(dp), intent(out) :: w(n)
230 : :
231 : : !Local variables-------------------------------
232 : : integer :: info,lwork
233 : : real(dp),pointer :: rwork(:)
234 : : complex(dp),pointer :: work(:)
235 : : ! *********************************************************************
236 : :
237 [ # # ]: 0 : ABI_CHECK(lapack_full_storage,"BUG(1) in abi_zheev (storage)!")
238 [ # # ]: 0 : ABI_CHECK(lapack_double_precision,"BUG(2) in abi_zheev (precision)!")
239 [ # # ]: 0 : ABI_CHECK(n<=eigen_z_maxsize,"BUG(3) in abi_zheev (maxsize)!")
240 : :
241 : : #if defined(DEBUG_VERBOSE) && defined(HAVE_OPENMP_OFFLOAD)
242 : : if ( gpu_option_ == ABI_GPU_OPENMP ) then
243 : : ABI_CHECK(xomp_target_is_present(c_loc(a)), "Array isn't mapped on GPU")
244 : : ABI_CHECK(xomp_target_is_present(c_loc(w)), "Array isn't mapped on GPU")
245 : : end if
246 : : #endif
247 : :
248 : 0 : work => eigen_z_work ; rwork => eigen_z_rwork
249 : 0 : lwork=eigen_z_lwork
250 : :
251 : : !===== PLASMA
252 : : !FDahm & LNGuyen (November 2012) :
253 : : ! In Plasma v 2.4.6, eigen routines support only
254 : : ! the eigenvalues computation (jobz=N) and not the
255 : : ! full eigenvectors bases determination (jobz=V)
256 [ # # # # ]: 0 : if (ABI_LINALG_PLASMA_ISON.and.LSAME(jobz,'N')) then
257 : : #if defined HAVE_LINALG_PLASMA
258 : : if (eigen_z_lwork==0) then
259 : : ABI_MALLOC(work,(n**2))
260 : : end if
261 : : call PLASMA_Alloc_Workspace_zheev(n,n,plasma_work,info)
262 : : info = PLASMA_zheev_c(jobz_plasma(jobz),uplo_plasma(uplo),&
263 : : & plasma_work,c_loc(work),n)
264 : : call PLASMA_Dealloc_handle(plasma_work,info)
265 : : if (eigen_z_lwork==0) then
266 : : ABI_FREE(work)
267 : : end if
268 : : #endif
269 : :
270 : : !===== LAPACK
271 : : else
272 [ # # ]: 0 : if (eigen_z_lwork==0) then
273 : 0 : lwork=2*n-1
274 [ # # # # : 0 : ABI_MALLOC(work,(lwork))
# # # # #
# # # ]
275 : : end if
276 [ # # ]: 0 : if (eigen_z_lrwork==0) then
277 [ # # # # : 0 : ABI_MALLOC(rwork,(3*n-2))
# # # # #
# # # #
# ]
278 : : end if
279 [ # # # # ]: 0 : call zheev(jobz,uplo,n,a,lda,w,work,lwork,rwork,info)
280 [ # # ]: 0 : if (eigen_z_lwork==0) then
281 [ # # ]: 0 : ABI_FREE(work)
282 : : end if
283 [ # # ]: 0 : if (eigen_z_lrwork==0) then
284 [ # # ]: 0 : ABI_FREE(rwork)
285 : : end if
286 : : end if
287 : :
288 [ # # ]: 0 : ABI_CHECK(info==0,"abi_zheev returned info !=0!")
289 : :
290 : 0 : end subroutine abi_zheev
291 : : !!***
292 : :
293 : : !----------------------------------------------------------------------
294 : :
295 : : !!****f* m_abi_linalg/abi_d2zheevd
296 : : !! NAME
297 : : !! abi_d2zheevd
298 : : !!
299 : : !! FUNCTION
300 : : !! Generic divide-and-conquer eigensolver (HEEVD/SYEVD) with GPU support.
301 : : !! Accepts real storage (real or complex-as-real via x_cplx).
302 : : !! On GPU, calls abi_gpu_xheevd_cptr. On CPU, self-manages work arrays.
303 : : !!
304 : : !! INPUTS
305 : : !!
306 : : !! SOURCE
307 : :
308 [ # # # # ]: 0 : subroutine abi_d2zheevd(jobz, uplo, n, a, lda, w, info, x_cplx, gpu_option)
309 : :
310 : : !Arguments ------------------------------------
311 : : character(len=1), intent(in) :: jobz
312 : : character(len=1), intent(in) :: uplo
313 : : integer, intent(in) :: n, lda
314 : : real(dp), target, intent(inout) :: a(:,:)
315 : : real(dp), target, intent(out) :: w(:,:)
316 : : integer, intent(out) :: info
317 : : !Optionals -----------------------------------
318 : : integer, intent(in), optional :: x_cplx
319 : : integer, intent(in), optional :: gpu_option
320 : :
321 : : !Local variables-------------------------------
322 : : integer :: cplx_, gpu_option_
323 : : integer :: lwork, lrwork, liwork
324 : 0 : real(dp), pointer :: rwork(:)
325 : 0 : complex(dp), pointer :: cwork(:)
326 : 0 : integer, pointer :: iwork(:)
327 : : real(dp) :: rwork_query(1)
328 : : complex(dp) :: cwork_query(1)
329 : : integer :: iwork_query(1)
330 : :
331 : : ! *********************************************************************
332 : :
333 : 0 : cplx_=1 ; if(PRESENT(x_cplx)) cplx_ = x_cplx
334 [ # # ]: 0 : gpu_option_=ABI_GPU_DISABLED ; if(PRESENT(gpu_option)) gpu_option_ = gpu_option
335 : :
336 : : #if defined(DEBUG_VERBOSE) && defined(HAVE_OPENMP_OFFLOAD)
337 : : if ( gpu_option_ == ABI_GPU_OPENMP ) then
338 : : ABI_CHECK(xomp_target_is_present(c_loc(a)), "Array isn't mapped on GPU")
339 : : ABI_CHECK(xomp_target_is_present(c_loc(w)), "Array isn't mapped on GPU")
340 : : end if
341 : : #endif
342 : :
343 [ # # ]: 0 : if(gpu_option_/=ABI_GPU_DISABLED) then
344 [ # # ]: 0 : if(gpu_option_==ABI_GPU_OPENMP) then
345 : : #ifdef HAVE_OPENMP_OFFLOAD
346 : : !$OMP TARGET DATA USE_DEVICE_ADDR(a,w)
347 : : call abi_gpu_xheevd_cptr(cplx_, jobz, uplo, n, c_loc(a), lda, c_loc(w), info)
348 : : !$OMP END TARGET DATA
349 : : #endif
350 : : else
351 : 0 : call abi_gpu_xheevd_cptr(cplx_, jobz, uplo, n, c_loc(a), lda, c_loc(w), info)
352 : : end if
353 : : else
354 [ # # ]: 0 : if(cplx_ == 2) then
355 : 0 : lwork=-1 ; lrwork=-1 ; liwork=-1
356 [ # # # # : 0 : call zheevd(jobz, uplo, n, a, lda, w, cwork_query, lwork, rwork_query, lrwork, iwork_query, liwork, info)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
357 : 0 : lwork=int(cwork_query(1)) ; lrwork=int(rwork_query(1)) ; liwork=iwork_query(1)
358 [ # # # # : 0 : ABI_MALLOC(cwork, (lwork))
# # # # #
# # # ]
359 [ # # # # : 0 : ABI_MALLOC(rwork, (lrwork))
# # # # #
# # # ]
360 [ # # # # : 0 : ABI_MALLOC(iwork, (liwork))
# # # # #
# # # ]
361 [ # # # # : 0 : call zheevd(jobz, uplo, n, a, lda, w, cwork, lwork, rwork, lrwork, iwork, liwork, info)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
362 [ # # # # : 0 : ABI_FREE(cwork) ; ABI_FREE(rwork) ; ABI_FREE(iwork)
# # ]
363 : : else
364 : 0 : lwork=-1 ; liwork=-1
365 [ # # # # : 0 : call dsyevd(jobz, uplo, n, a, lda, w, rwork_query, lwork, iwork_query, liwork, info)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
366 : 0 : lwork=int(rwork_query(1)) ; liwork=iwork_query(1)
367 [ # # # # : 0 : ABI_MALLOC(rwork, (lwork))
# # # # #
# # # ]
368 [ # # # # : 0 : ABI_MALLOC(iwork, (liwork))
# # # # #
# # # ]
369 [ # # # # : 0 : call dsyevd(jobz, uplo, n, a, lda, w, rwork, lwork, iwork, liwork, info)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
370 [ # # # # ]: 0 : ABI_FREE(rwork) ; ABI_FREE(iwork)
371 : : end if
372 : : end if
373 : :
374 [ # # ]: 0 : ABI_CHECK(info==0,"abi_d2zheevd returned info!=0!")
375 : :
376 [ # # ]: 0 : end subroutine abi_d2zheevd
377 : : !!***
378 : :
379 : : !----------------------------------------------------------------------
380 : :
381 : : !!****f* m_abi_linalg/abi_zheevd_2d
382 : : !! NAME
383 : : !! abi_zheevd_2d
384 : : !!
385 : : !! FUNCTION
386 : : !! Divide-and-conquer complex Hermitian eigensolver (ZHEEVD) with GPU support.
387 : : !! Accepts complex(dp) 2D matrix. On GPU, calls abi_gpu_xheevd_cptr.
388 : : !! On CPU, self-manages work arrays.
389 : : !!
390 : : !! INPUTS
391 : : !!
392 : : !! SOURCE
393 : :
394 [ # # # # ]: 0 : subroutine abi_zheevd_2d(jobz, uplo, n, a, lda, w, info, gpu_option)
395 : :
396 : : !Arguments ------------------------------------
397 : : character(len=1), intent(in) :: jobz
398 : : character(len=1), intent(in) :: uplo
399 : : integer, intent(in) :: n, lda
400 : : complex(dp), target, intent(inout) :: a(:,:)
401 : : real(dp), target, intent(out) :: w(:,:)
402 : : integer, intent(out) :: info
403 : : !Optionals -----------------------------------
404 : : integer, intent(in), optional :: gpu_option
405 : :
406 : : !Local variables-------------------------------
407 : : integer :: gpu_option_
408 : : integer :: lwork, lrwork, liwork
409 : 0 : complex(dp), pointer :: cwork(:)
410 : 0 : real(dp), pointer :: rwork(:)
411 : 0 : integer, pointer :: iwork(:)
412 : : complex(dp) :: cwork_query(1)
413 : : real(dp) :: rwork_query(1)
414 : : integer :: iwork_query(1)
415 : :
416 : : ! *********************************************************************
417 : :
418 : 0 : gpu_option_=ABI_GPU_DISABLED ; if(PRESENT(gpu_option)) gpu_option_ = gpu_option
419 : :
420 [ # # ]: 0 : if(gpu_option_/=ABI_GPU_DISABLED) then
421 [ # # ]: 0 : if(gpu_option_==ABI_GPU_OPENMP) then
422 : : #ifdef HAVE_OPENMP_OFFLOAD
423 : : !$OMP TARGET DATA USE_DEVICE_ADDR(a,w)
424 : : call abi_gpu_xheevd_cptr(2, jobz, uplo, n, c_loc(a), lda, c_loc(w), info)
425 : : !$OMP END TARGET DATA
426 : : #endif
427 : : else
428 : 0 : call abi_gpu_xheevd_cptr(2, jobz, uplo, n, c_loc(a), lda, c_loc(w), info)
429 : : end if
430 : : else
431 : 0 : lwork=-1 ; lrwork=-1 ; liwork=-1
432 [ # # # # : 0 : call zheevd(jobz, uplo, n, a, lda, w, cwork_query, lwork, rwork_query, lrwork, iwork_query, liwork, info)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
433 : 0 : lwork=int(cwork_query(1)) ; lrwork=int(rwork_query(1)) ; liwork=iwork_query(1)
434 [ # # # # : 0 : ABI_MALLOC(cwork, (lwork))
# # # # #
# # # ]
435 [ # # # # : 0 : ABI_MALLOC(rwork, (lrwork))
# # # # #
# # # ]
436 [ # # # # : 0 : ABI_MALLOC(iwork, (liwork))
# # # # #
# # # ]
437 [ # # # # : 0 : call zheevd(jobz, uplo, n, a, lda, w, cwork, lwork, rwork, lrwork, iwork, liwork, info)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
438 [ # # # # : 0 : ABI_FREE(cwork) ; ABI_FREE(rwork) ; ABI_FREE(iwork)
# # ]
439 : : end if
440 : :
441 [ # # ]: 0 : ABI_CHECK(info==0,"abi_zheevd_2d returned info!=0!")
442 : :
443 [ # # ]: 0 : end subroutine abi_zheevd_2d
444 : : !!***
|