Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Wrapper for cuSOLVERMp
10 : !> \author Ole Schuett
11 : ! **************************************************************************************************
12 : MODULE cp_fm_cusolver_api
13 : USE ISO_C_BINDING, ONLY: C_DOUBLE,&
14 : C_DOUBLE_COMPLEX,&
15 : C_INT
16 : USE cp_blacs_env, ONLY: cp_blacs_env_type
17 : USE cp_cfm_types, ONLY: cp_cfm_type
18 : USE cp_fm_types, ONLY: cp_fm_type
19 : USE kinds, ONLY: dp
20 : #include "../base/base_uses.f90"
21 :
22 : IMPLICIT NONE
23 :
24 : PRIVATE
25 :
26 : PUBLIC :: cp_fm_diag_cusolver
27 : PUBLIC :: cp_cfm_general_cusolver
28 : PUBLIC :: cp_fm_general_cusolver
29 :
30 : CONTAINS
31 :
32 : ! **************************************************************************************************
33 : !> \brief Driver routine to diagonalize a FM matrix with the cuSOLVERMp library.
34 : !> \param matrix the matrix that is diagonalized
35 : !> \param eigenvectors eigenvectors of the input matrix
36 : !> \param eigenvalues eigenvalues of the input matrix
37 : !> \author Ole Schuett
38 : ! **************************************************************************************************
39 0 : SUBROUTINE cp_fm_diag_cusolver(matrix, eigenvectors, eigenvalues)
40 : TYPE(cp_fm_type), INTENT(IN) :: matrix, eigenvectors
41 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: eigenvalues
42 :
43 : CHARACTER(len=*), PARAMETER :: routineN = 'cp_fm_diag_cusolver'
44 :
45 : INTEGER :: handle, n, nmo
46 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues_buffer
47 : TYPE(cp_blacs_env_type), POINTER :: context
48 : INTERFACE
49 : SUBROUTINE cp_fm_diag_cusolver_c(fortran_comm, matrix_desc, &
50 : nprow, npcol, myprow, mypcol, &
51 : n, matrix, eigenvectors, eigenvalues) &
52 : BIND(C, name="cp_fm_diag_cusolver")
53 : IMPORT :: C_INT, C_DOUBLE
54 : INTEGER(kind=C_INT), VALUE :: fortran_comm
55 : INTEGER(kind=C_INT), DIMENSION(*) :: matrix_desc
56 : INTEGER(kind=C_INT), VALUE :: nprow
57 : INTEGER(kind=C_INT), VALUE :: npcol
58 : INTEGER(kind=C_INT), VALUE :: myprow
59 : INTEGER(kind=C_INT), VALUE :: mypcol
60 : INTEGER(kind=C_INT), VALUE :: n
61 : REAL(kind=C_DOUBLE), DIMENSION(*) :: matrix
62 : REAL(kind=C_DOUBLE), DIMENSION(*) :: eigenvectors
63 : REAL(kind=C_DOUBLE), DIMENSION(*) :: eigenvalues
64 : END SUBROUTINE cp_fm_diag_cusolver_c
65 : END INTERFACE
66 :
67 0 : CALL timeset(routineN, handle)
68 :
69 : #if defined(__CUSOLVERMP)
70 : n = matrix%matrix_struct%nrow_global
71 : context => matrix%matrix_struct%context
72 :
73 : ! The passed eigenvalues array might be smaller than n.
74 : ALLOCATE (eigenvalues_buffer(n))
75 :
76 : CALL cp_fm_diag_cusolver_c( &
77 : fortran_comm=matrix%matrix_struct%para_env%get_handle(), &
78 : matrix_desc=matrix%matrix_struct%descriptor, &
79 : nprow=context%num_pe(1), &
80 : npcol=context%num_pe(2), &
81 : myprow=context%mepos(1), &
82 : mypcol=context%mepos(2), &
83 : n=matrix%matrix_struct%nrow_global, &
84 : matrix=matrix%local_data, &
85 : eigenvectors=eigenvectors%local_data, &
86 : eigenvalues=eigenvalues_buffer)
87 :
88 : nmo = SIZE(eigenvalues)
89 : eigenvalues(1:nmo) = eigenvalues_buffer(1:nmo)
90 :
91 : #else
92 : MARK_USED(matrix)
93 : MARK_USED(eigenvectors)
94 0 : eigenvalues = 0.0_dp
95 : MARK_USED(n)
96 : MARK_USED(nmo)
97 : MARK_USED(eigenvalues_buffer)
98 : MARK_USED(context)
99 0 : CPABORT("CP2K compiled without the cuSOLVERMp library.")
100 : #endif
101 :
102 0 : CALL timestop(handle)
103 0 : END SUBROUTINE cp_fm_diag_cusolver
104 :
105 : ! **************************************************************************************************
106 : !> \brief Driver routine to solve generalized eigenvalue problem A*x = lambda*B*x with cuSOLVERMp.
107 : !> \param aMatrix the first matrix for the generalized eigenvalue problem
108 : !> \param bMatrix the second matrix for the generalized eigenvalue problem
109 : !> \param eigenvectors eigenvectors of the input matrix
110 : !> \param eigenvalues eigenvalues of the input matrix
111 : ! **************************************************************************************************
112 0 : SUBROUTINE cp_fm_general_cusolver(aMatrix, bMatrix, eigenvectors, eigenvalues)
113 : USE ISO_C_BINDING, ONLY: C_INT, C_DOUBLE
114 : TYPE(cp_fm_type), INTENT(IN) :: aMatrix, bMatrix, eigenvectors
115 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: eigenvalues
116 :
117 : CHARACTER(len=*), PARAMETER :: routineN = 'cp_fm_general_cusolver'
118 :
119 : INTEGER(kind=C_INT) :: handle, n, nmo
120 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues_buffer
121 : TYPE(cp_blacs_env_type), POINTER :: context
122 : INTERFACE
123 : SUBROUTINE cp_fm_general_cusolver_c(fortran_comm, a_matrix_desc, b_matrix_desc, &
124 : nprow, npcol, myprow, mypcol, &
125 : n, aMatrix, bMatrix, eigenvectors, eigenvalues) &
126 : BIND(C, name="cp_fm_diag_cusolver_sygvd")
127 : IMPORT :: C_INT, C_DOUBLE
128 : INTEGER(kind=C_INT), VALUE :: fortran_comm
129 : INTEGER(kind=C_INT), DIMENSION(*) :: a_matrix_desc, b_matrix_desc
130 : INTEGER(kind=C_INT), VALUE :: nprow
131 : INTEGER(kind=C_INT), VALUE :: npcol
132 : INTEGER(kind=C_INT), VALUE :: myprow
133 : INTEGER(kind=C_INT), VALUE :: mypcol
134 : INTEGER(kind=C_INT), VALUE :: n
135 : REAL(kind=C_DOUBLE), DIMENSION(*) :: aMatrix
136 : REAL(kind=C_DOUBLE), DIMENSION(*) :: bMatrix
137 : REAL(kind=C_DOUBLE), DIMENSION(*) :: eigenvectors
138 : REAL(kind=C_DOUBLE), DIMENSION(*) :: eigenvalues
139 : END SUBROUTINE cp_fm_general_cusolver_c
140 : END INTERFACE
141 :
142 0 : CALL timeset(routineN, handle)
143 :
144 : #if defined(__CUSOLVERMP)
145 : n = INT(aMatrix%matrix_struct%nrow_global, C_INT)
146 : context => aMatrix%matrix_struct%context
147 :
148 : ! Allocate eigenvalues_buffer
149 : ALLOCATE (eigenvalues_buffer(n))
150 :
151 : CALL cp_fm_general_cusolver_c( &
152 : fortran_comm=INT(aMatrix%matrix_struct%para_env%get_handle(), C_INT), &
153 : a_matrix_desc=INT(aMatrix%matrix_struct%descriptor, C_INT), &
154 : b_matrix_desc=INT(bMatrix%matrix_struct%descriptor, C_INT), &
155 : nprow=INT(context%num_pe(1), C_INT), &
156 : npcol=INT(context%num_pe(2), C_INT), &
157 : myprow=INT(context%mepos(1), C_INT), &
158 : mypcol=INT(context%mepos(2), C_INT), &
159 : n=n, &
160 : aMatrix=aMatrix%local_data, &
161 : bMatrix=bMatrix%local_data, &
162 : eigenvectors=eigenvectors%local_data, &
163 : eigenvalues=eigenvalues_buffer)
164 :
165 : nmo = SIZE(eigenvalues)
166 : eigenvalues(1:nmo) = eigenvalues_buffer(1:nmo)
167 :
168 : DEALLOCATE (eigenvalues_buffer)
169 : #else
170 : MARK_USED(aMatrix)
171 : MARK_USED(bMatrix)
172 : MARK_USED(eigenvectors)
173 0 : eigenvalues = 0.0_dp
174 : MARK_USED(n)
175 : MARK_USED(nmo)
176 : MARK_USED(eigenvalues_buffer)
177 : MARK_USED(context)
178 0 : CPABORT("CP2K compiled without the cuSOLVERMp library.")
179 : #endif
180 :
181 0 : CALL timestop(handle)
182 0 : END SUBROUTINE cp_fm_general_cusolver
183 :
184 : ! **************************************************************************************************
185 : !> \brief Driver routine to solve generalized complex eigenvalue problem A*x = lambda*B*x with
186 : !> cuSOLVERMp.
187 : !> \param aMatrix the first matrix for the generalized eigenvalue problem
188 : !> \param bMatrix the second matrix for the generalized eigenvalue problem
189 : !> \param eigenvectors eigenvectors of the input matrix
190 : !> \param eigenvalues eigenvalues of the input matrix
191 : ! **************************************************************************************************
192 0 : SUBROUTINE cp_cfm_general_cusolver(aMatrix, bMatrix, eigenvectors, eigenvalues)
193 : USE ISO_C_BINDING, ONLY: C_DOUBLE, C_DOUBLE_COMPLEX, C_INT
194 : TYPE(cp_cfm_type), INTENT(IN) :: aMatrix, bMatrix, eigenvectors
195 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: eigenvalues
196 :
197 : CHARACTER(len=*), PARAMETER :: routineN = 'cp_cfm_general_cusolver'
198 :
199 : INTEGER(kind=C_INT) :: handle, n, nmo
200 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues_buffer
201 : TYPE(cp_blacs_env_type), POINTER :: context
202 : INTERFACE
203 : SUBROUTINE cp_cfm_general_cusolver_c(fortran_comm, a_matrix_desc, b_matrix_desc, &
204 : nprow, npcol, myprow, mypcol, &
205 : n, aMatrix, bMatrix, eigenvectors, eigenvalues) &
206 : BIND(C, name="cp_cfm_diag_cusolver_hegvd")
207 : IMPORT :: C_DOUBLE, C_DOUBLE_COMPLEX, C_INT
208 : INTEGER(kind=C_INT), VALUE :: fortran_comm
209 : INTEGER(kind=C_INT), DIMENSION(*) :: a_matrix_desc, b_matrix_desc
210 : INTEGER(kind=C_INT), VALUE :: nprow
211 : INTEGER(kind=C_INT), VALUE :: npcol
212 : INTEGER(kind=C_INT), VALUE :: myprow
213 : INTEGER(kind=C_INT), VALUE :: mypcol
214 : INTEGER(kind=C_INT), VALUE :: n
215 : COMPLEX(kind=C_DOUBLE_COMPLEX), DIMENSION(*) :: aMatrix
216 : COMPLEX(kind=C_DOUBLE_COMPLEX), DIMENSION(*) :: bMatrix
217 : COMPLEX(kind=C_DOUBLE_COMPLEX), DIMENSION(*) :: eigenvectors
218 : REAL(kind=C_DOUBLE), DIMENSION(*) :: eigenvalues
219 : END SUBROUTINE cp_cfm_general_cusolver_c
220 : END INTERFACE
221 :
222 0 : CALL timeset(routineN, handle)
223 :
224 : #if defined(__CUSOLVERMP)
225 : n = INT(aMatrix%matrix_struct%nrow_global, C_INT)
226 : context => aMatrix%matrix_struct%context
227 :
228 : ALLOCATE (eigenvalues_buffer(n))
229 :
230 : CALL cp_cfm_general_cusolver_c( &
231 : fortran_comm=INT(aMatrix%matrix_struct%para_env%get_handle(), C_INT), &
232 : a_matrix_desc=INT(aMatrix%matrix_struct%descriptor, C_INT), &
233 : b_matrix_desc=INT(bMatrix%matrix_struct%descriptor, C_INT), &
234 : nprow=INT(context%num_pe(1), C_INT), &
235 : npcol=INT(context%num_pe(2), C_INT), &
236 : myprow=INT(context%mepos(1), C_INT), &
237 : mypcol=INT(context%mepos(2), C_INT), &
238 : n=n, &
239 : aMatrix=aMatrix%local_data, &
240 : bMatrix=bMatrix%local_data, &
241 : eigenvectors=eigenvectors%local_data, &
242 : eigenvalues=eigenvalues_buffer)
243 :
244 : nmo = SIZE(eigenvalues)
245 : eigenvalues(1:nmo) = eigenvalues_buffer(1:nmo)
246 :
247 : DEALLOCATE (eigenvalues_buffer)
248 : #else
249 : MARK_USED(aMatrix)
250 : MARK_USED(bMatrix)
251 : MARK_USED(eigenvectors)
252 0 : eigenvalues = 0.0_dp
253 : MARK_USED(n)
254 : MARK_USED(nmo)
255 : MARK_USED(eigenvalues_buffer)
256 : MARK_USED(context)
257 0 : CPABORT("CP2K compiled without the cuSOLVERMp library.")
258 : #endif
259 :
260 0 : CALL timestop(handle)
261 0 : END SUBROUTINE cp_cfm_general_cusolver
262 :
263 : END MODULE cp_fm_cusolver_api
|