Branch data Line data Source code
1 : : !!****m* ABINIT/m_alloc_hamilt_gpu
2 : : !! NAME
3 : : !! m_alloc_hamilt_gpu
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 2000-2026 ABINIT group (MT, FDahm)
9 : : !! This file is distributed under the terms of the
10 : : !! GNU General Public License, see ~abinit/COPYING
11 : : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : : !!
13 : : !! SOURCE
14 : :
15 : : #if defined HAVE_CONFIG_H
16 : : #include "config.h"
17 : : #endif
18 : :
19 : : #include "abi_common.h"
20 : :
21 : : module m_alloc_hamilt_gpu
22 : :
23 : : use defs_basis
24 : : use m_abicore
25 : : use m_errors
26 : : use m_xmpi
27 : : use m_dtset
28 : : use m_errors
29 : : use m_ompgpu_fourwf
30 : : #if defined HAVE_GPU
31 : : use m_gpu_toolbox
32 : : use m_gputk
33 : : #endif
34 : :
35 : : #ifdef HAVE_FC_ISO_C_BINDING
36 : : use, intrinsic :: iso_c_binding
37 : : #endif
38 : :
39 : : use defs_datatypes, only : pseudopotential_type
40 : : use defs_abitypes, only : MPI_type
41 : :
42 : : implicit none
43 : :
44 : : private
45 : : !!***
46 : :
47 : : public :: alloc_hamilt_gpu
48 : : public :: dealloc_hamilt_gpu
49 : : !!***
50 : :
51 : : private :: alloc_nonlop_gpu_data
52 : : private :: dealloc_nonlop_gpu_data
53 : :
54 : : !! data type to store pointers to data used on GPU, mostly in gemm nonlop_gpu
55 : : !! opernla/b/c
56 : : type, public :: gemm_nonlop_gpu_data_type
57 : :
58 : : logical :: allocated
59 : : type(c_ptr) :: projections_gpu
60 : : type(c_ptr) :: s_projections_gpu
61 : : type(c_ptr) :: vnl_projections_gpu
62 : :
63 : : type(c_ptr) :: vectin_gpu
64 : : type(c_ptr) :: vectout_gpu
65 : : type(c_ptr) :: svectout_gpu
66 : :
67 : : end type gemm_nonlop_gpu_data_type
68 : :
69 : : type(gemm_nonlop_gpu_data_type), save, public, target :: gemm_nonlop_gpu_data
70 : :
71 : : integer, save, public :: hamilt_gpu_nfft_blocks
72 : :
73 : : contains
74 : : !!***
75 : :
76 : : !!****f* ABINIT/alloc_hamilt_gpu
77 : : !! NAME
78 : : !! alloc_hamilt_gpu
79 : : !!
80 : : !! FUNCTION
81 : : !! allocate several memory pieces on a GPU device for the application
82 : : !! of Hamiltonian using a GPU
83 : : !!
84 : : !! INPUTS
85 : : !! atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
86 : : !! dtset <type(dataset_type)>=all input variables for this dataset
87 : : !! gprimd(3,3)=dimensional reciprocal space primitive translations
88 : : !! mpi_enreg=information about MPI parallelization
89 : : !! nattyp(ntypat)= # atoms of each type.
90 : : !! option=0: allocate data for local operator (FFT)
91 : : !! 1: allocate data for nonlocal operator
92 : : !! 2: allocate both
93 : : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
94 : : !! gpu_option= GPU implementation to use, i.e. cuda, openMP, ... (0=not using GPU)
95 : : !!
96 : : !! OUTPUT
97 : : !! (no output - only allocation on GPU)
98 : : !!
99 : : !! SOURCE
100 : :
101 : 0 : subroutine alloc_hamilt_gpu(atindx1,dtset,gprimd,mpi_enreg,nattyp,npwarr,option,psps,gpu_option)
102 : :
103 : : !Arguments ------------------------------------
104 : : !scalars
105 : : integer,intent(in) :: option,gpu_option
106 : : type(dataset_type),intent(in) :: dtset
107 : : type(MPI_type),intent(in) :: mpi_enreg
108 : : type(pseudopotential_type),intent(in) :: psps
109 : : !arrays
110 : : integer,intent(in) :: atindx1(dtset%natom),nattyp(dtset%ntypat),npwarr(dtset%nkpt)
111 : : real(dp),intent(in) :: gprimd(3,3)
112 : :
113 : : !Local variables-------------------------------
114 : : !scalars
115 : : #if defined HAVE_GPU
116 : : integer :: dimekb1_max,dimekb2_max,dimffnl_max,ierr,ikpt,npw_max_loc,npw_max_nonloc
117 : : integer :: cplex
118 : : integer ::npwarr_tmp(dtset%nkpt)
119 : :
120 : : integer(kind=c_int32_t) :: proj_dim(3)
121 : : #endif
122 : :
123 : : ! *************************************************************************
124 : :
125 : : if (gpu_option==ABI_GPU_DISABLED) return
126 : :
127 : : #if defined(HAVE_GPU)
128 : : !=== Local Hamiltonian ===
129 : : if (option==0.or.option==2) then
130 : : ! Compute max of total planes waves
131 : : npw_max_loc=0
132 : : if(mpi_enreg%paral_kgb==1) then
133 : : npwarr_tmp=npwarr
134 : : call xmpi_sum(npwarr_tmp,mpi_enreg%comm_bandfft,ierr)
135 : : npw_max_loc =maxval(npwarr_tmp)
136 : : else
137 : : npw_max_loc=dtset%mpw
138 : : end if
139 : : ! Initialize gpu data needed in fourwf
140 : : ! ndat=bandpp when paral_kgb=1
141 : : ! no matter paral_kgb=0 or 1, we gathet all bands into a single call gpu_fourwf
142 : : if(gpu_option == ABI_GPU_LEGACY) then
143 : : #if defined(HAVE_GPU_CUDA) && defined(HAVE_FC_ISO_C_BINDING)
144 : : call alloc_gpu_fourwf(dtset%ngfft,dtset%bandpp,npw_max_loc,npw_max_loc)
145 : : #endif
146 : : else if (gpu_option == ABI_GPU_KOKKOS) then
147 : : #if defined(HAVE_GPU_CUDA) && defined(HAVE_FC_ISO_C_BINDING)
148 : : call alloc_gpu_fourwf_managed(dtset%ngfft,dtset%bandpp,npw_max_loc,npw_max_loc)
149 : : #endif
150 : : else if (gpu_option == ABI_GPU_OPENMP) then
151 : : !call alloc_ompgpu_fourwf(dtset%ngfft,dtset%bandpp)
152 : : end if
153 : :
154 : : end if
155 : : !=== Nonlocal Hamiltonian ===
156 : : if (option==1.or.option==2) then
157 : : ! Compute max of total planes waves
158 : : npw_max_nonloc=0
159 : : if(mpi_enreg%paral_kgb==1) then
160 : : npwarr_tmp=npwarr
161 : : call xmpi_sum(npwarr_tmp,mpi_enreg%comm_band,ierr)
162 : : npw_max_nonloc =maxval(npwarr_tmp)
163 : : else
164 : : npw_max_nonloc=dtset%mpw
165 : : end if
166 : : ! Initialize all gpu data needed in nonlop
167 : : dimffnl_max=4
168 : : ! if (abs(dtset%berryopt) == 5) dimffnl_max=4
169 : : dimekb1_max=psps%dimekb
170 : : if (dtset%usepaw==0) dimekb2_max=psps%ntypat
171 : : if (dtset%usepaw==1) dimekb2_max=dtset%natom
172 : :
173 : : if (gpu_option == ABI_GPU_KOKKOS .or. gpu_option == ABI_GPU_LEGACY) then
174 : :
175 : : #if defined(HAVE_GPU_CUDA) && defined(HAVE_FC_ISO_C_BINDING)
176 : : ! TODO (PK) : disable this allocation when Kokkos is available
177 : : ! to save memory on GPU side
178 : : call alloc_nonlop_gpu(npw_max_nonloc, &
179 : : & npw_max_nonloc,&
180 : : & dtset%nspinor,&
181 : : & dtset%natom,&
182 : : & dtset%ntypat,&
183 : : & psps%lmnmax,&
184 : : & psps%indlmn,&
185 : : & nattyp,&
186 : : & atindx1,&
187 : : & gprimd,&
188 : : & dimffnl_max,&
189 : : & dimffnl_max,&
190 : : & dimekb1_max,&
191 : : & dimekb2_max)
192 : :
193 : : if (dtset%use_gemm_nonlop == 1) then
194 : : call alloc_nonlop_gpu_data(dtset, &
195 : : & psps, &
196 : : & npw_max_nonloc,&
197 : : & npw_max_nonloc,&
198 : : & atindx1,&
199 : : & nattyp,&
200 : : & gpu_option)
201 : : end if
202 : : #endif
203 : :
204 : : end if
205 : :
206 : : end if ! option 1 or 2
207 : :
208 : : call xmpi_barrier(mpi_enreg%comm_cell)
209 : :
210 : : #else
211 : :
212 : : ABI_UNUSED(npwarr)
213 : : ABI_UNUSED_A(psps)
214 : : if (.false.) then
215 : : write(std_out,*) atindx1(1),dtset%natom,gprimd(1,1),mpi_enreg%me,nattyp(1),option
216 : : end if
217 : :
218 : : #endif
219 : :
220 : : end subroutine alloc_hamilt_gpu
221 : : !!***
222 : :
223 : : !!****f* ABINIT/dealloc_hamilt_gpu
224 : : !! NAME
225 : : !! dealloc_hamilt_gpu
226 : : !!
227 : : !! FUNCTION
228 : : !! deallocate several memory pieces on a GPU device used for the application
229 : : !! of Hamiltonian using a GPU
230 : : !!
231 : : !! INPUTS
232 : : !! option=0: deallocate data for local operator (FFT)
233 : : !! 1: deallocate data for nonlocal operator
234 : : !! 2: deallocate both
235 : : !! gpu_option= GPU implementation to use, i.e. cuda, openMP, ... (0=not using GPU)
236 : : !!
237 : : !! OUTPUT
238 : : !! (no output - only deallocation on GPU)
239 : : !!
240 : : !! SOURCE
241 : :
242 : 0 : subroutine dealloc_hamilt_gpu(option,gpu_option)
243 : :
244 : : !Arguments ------------------------------------
245 : : !scalars
246 : : integer,intent(in) :: option,gpu_option
247 : : !arrays
248 : :
249 : : !Local variables-------------------------------
250 : :
251 : : ! *************************************************************************
252 : :
253 [ # # ]: 0 : if (gpu_option==ABI_GPU_DISABLED) return
254 : :
255 [ # # ]: 0 : if (gpu_option == ABI_GPU_KOKKOS .or. gpu_option == ABI_GPU_LEGACY) then
256 : : #if defined(HAVE_GPU_CUDA) && defined(HAVE_FC_ISO_C_BINDING)
257 : : if (option==0.or.option==2) then
258 : : if (gpu_option == ABI_GPU_LEGACY) then
259 : : call free_gpu_fourwf()
260 : : else if(gpu_option == ABI_GPU_KOKKOS) then
261 : : call free_gpu_fourwf_managed()
262 : : end if
263 : : end if
264 : :
265 : : if (option==1.or.option==2) then
266 : : call free_nonlop_gpu()
267 : : call dealloc_nonlop_gpu_data()
268 : : end if ! option 1 or 2
269 : : #endif
270 [ # # ]: 0 : else if(gpu_option == ABI_GPU_OPENMP) then
271 : 0 : call free_ompgpu_fourwf()
272 : : end if
273 : :
274 : : if (.false.) then
275 : : write(std_out,*) option
276 : : end if
277 : :
278 : : end subroutine dealloc_hamilt_gpu
279 : : !!***
280 : :
281 : : !!****f* ABINIT/alloc_nonlop_gpu_data
282 : : !! NAME
283 : : !! alloc_hamilt_gpu
284 : : !!
285 : : !! FUNCTION
286 : : !! allocate several memory pieces on a GPU device for the application
287 : : !! of Hamiltonian using a GPU
288 : : !!
289 : : !! INPUTS
290 : : !! atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
291 : : !! dtset <type(dataset_type)>=all input variables for this dataset
292 : : !! nattyp(ntypat)= # atoms of each type.
293 : : !! npwin is the number of plane waves for vectin
294 : : !! npwout is the number of plane waves for vectout
295 : : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
296 : : !! gpu_option= GPU implementation to use, i.e. cuda, openMP, ... (0=not using GPU)
297 : : !!
298 : : !! OUTPUT
299 : : !! (no output - only allocation on GPU, member of gemm_nonlop_gpu_data)
300 : : !!
301 : : !! SOURCE
302 : :
303 : : subroutine alloc_nonlop_gpu_data(dtset,&
304 : : & psps,&
305 : : & npwin,&
306 : : & npwout,&
307 : : & atindx1,&
308 : : & nattyp,&
309 : : & gpu_option)
310 : :
311 : : !Arguments ------------------------------------
312 : : !scalars
313 : : type(dataset_type), intent(in) :: dtset
314 : : type(pseudopotential_type),intent(in) :: psps
315 : : integer, intent(in) :: npwin
316 : : integer, intent(in) :: npwout
317 : : integer, intent(in) :: atindx1(dtset%natom)
318 : : !arrays
319 : : integer, intent(in) :: nattyp(dtset%ntypat)
320 : : !integer, intent(in) :: npwarr(dtset%nkpt)
321 : :
322 : : ! other
323 : : integer, intent(in) :: gpu_option
324 : :
325 : : !Local variables-------------------------------
326 : : !scalars
327 : : #if defined HAVE_GPU_CUDA
328 : : integer :: cplex
329 : : integer :: nprojs
330 : : integer :: itypat
331 : :
332 : : real(dp) :: allocated_size_bytes
333 : : character(len=500) :: message
334 : : #endif
335 : :
336 : : ! *************************************************************************
337 : :
338 : : #if defined HAVE_GPU_CUDA
339 : : allocated_size_bytes = 0.
340 : :
341 : : cplex=2; !if (istwf_k>1) cplex=1
342 : :
343 : : ! compute nprojs
344 : : nprojs = 0
345 : : do itypat = 1,dtset%ntypat
346 : : nprojs = nprojs + count(psps%indlmn(3,:,itypat)>0) * nattyp(itypat)
347 : : end do
348 : :
349 : :
350 : : !! allocate memory on device
351 : :
352 : : if (gemm_nonlop_gpu_data % allocated .eqv. .false.) then
353 : : ! These will store the non-local factors for vectin, svectout and vectout respectively
354 : : ABI_MALLOC_CUDA(gemm_nonlop_gpu_data% projections_gpu, INT(cplex, c_size_t) * nprojs * dtset%nspinor*dtset%bandpp * dp)
355 : : ABI_MALLOC_CUDA(gemm_nonlop_gpu_data% s_projections_gpu, INT(cplex, c_size_t) * nprojs * dtset%nspinor*dtset%bandpp * dp)
356 : : ABI_MALLOC_CUDA(gemm_nonlop_gpu_data%vnl_projections_gpu, INT(2 , c_size_t) * nprojs * dtset%nspinor*dtset%bandpp * dp)
357 : :
358 : : allocated_size_bytes = allocated_size_bytes + (2*cplex+2)*nprojs * dtset%nspinor*dtset%bandpp * dp
359 : :
360 : : ABI_MALLOC_CUDA(gemm_nonlop_gpu_data% vectin_gpu, INT(2, c_size_t) * npwin * dtset%nspinor*dtset%bandpp * dp)
361 : : ABI_MALLOC_CUDA(gemm_nonlop_gpu_data% vectout_gpu, INT(2, c_size_t) * npwout * dtset%nspinor*dtset%bandpp * dp)
362 : : ABI_MALLOC_CUDA(gemm_nonlop_gpu_data% svectout_gpu, INT(2, c_size_t) * npwout * dtset%nspinor*dtset%bandpp * dp)
363 : :
364 : : allocated_size_bytes = allocated_size_bytes + &
365 : : & 2 * (npwin+2*npwout) * dtset%nspinor * dtset%bandpp * dp
366 : :
367 : : gemm_nonlop_gpu_data % allocated = .true.
368 : :
369 : : write(message,*) ' alloc_nonlop_gpu_data allocated ', allocated_size_bytes*1e-6, ' MBytes on device memory'
370 : : call wrtout(std_out,message,'COLL')
371 : :
372 : : end if
373 : :
374 : : #else
375 : :
376 : : if (.false.) then
377 : : write(std_out,*) psps%indlmn(1,1,1),dtset%natom,npwin,npwout,atindx1(1),nattyp(1),gpu_option
378 : : end if
379 : :
380 : : #endif
381 : :
382 : : end subroutine alloc_nonlop_gpu_data
383 : : !!***
384 : :
385 : : !!****f* ABINIT/dealloc_nonlop_gpu_data
386 : : !! NAME
387 : : !! dealloc_nonlop_gpu_data
388 : : !!
389 : : !! FUNCTION
390 : : !! deallocate several memory pieces on a GPU device used for the application
391 : : !! of nonlop operators using Kokkos implementation
392 : : !!
393 : : !!
394 : : !! OUTPUT
395 : : !! (no output - only deallocation on GPU)
396 : : !!
397 : : !! SOURCE
398 : :
399 : : subroutine dealloc_nonlop_gpu_data()
400 : :
401 : : #if defined HAVE_GPU_CUDA
402 : : if (gemm_nonlop_gpu_data % allocated) then
403 : : ABI_FREE_CUDA(gemm_nonlop_gpu_data% projections_gpu)
404 : : ABI_FREE_CUDA(gemm_nonlop_gpu_data% s_projections_gpu)
405 : : ABI_FREE_CUDA(gemm_nonlop_gpu_data%vnl_projections_gpu)
406 : :
407 : : ABI_FREE_CUDA(gemm_nonlop_gpu_data% vectin_gpu)
408 : : ABI_FREE_CUDA(gemm_nonlop_gpu_data% vectout_gpu)
409 : : ABI_FREE_CUDA(gemm_nonlop_gpu_data%svectout_gpu)
410 : :
411 : : gemm_nonlop_gpu_data % allocated = .false.
412 : : end if
413 : : #endif
414 : :
415 : : end subroutine dealloc_nonlop_gpu_data
416 : : !!***
417 : :
418 : 0 : end module m_alloc_hamilt_gpu
419 : : !!***
|