Line data Source code
1 : !!****m* ABINIT/m_prep_kgb
2 : !! NAME
3 : !! m_prep_kgb
4 : !!
5 : !! FUNCTION
6 : !! This module provides wrappers that used to apply the full Hamiltonian or just the Vnl part
7 : !! or to perform the FFT of the wavefunctions when the orbitals are distributed in linalg mode (paral_kgb = 1).
8 : !!
9 : !! COPYRIGHT
10 : !! Copyright (C) 1998-2026 ABINIT group (FBottin,MT,GZ,MD,FDahm)
11 : !! This file is distributed under the terms of the
12 : !! GNU General Public License, see ~abinit/COPYING
13 : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : !!
15 : !! SOURCE
16 :
17 : #if defined HAVE_CONFIG_H
18 : #include "config.h"
19 : #endif
20 :
21 : #include "abi_common.h"
22 :
23 : module m_prep_kgb
24 :
25 : use defs_basis
26 : use m_abicore
27 : use m_errors
28 : use m_xmpi
29 : use m_xomp
30 : use m_gputk
31 : use m_abi_linalg
32 :
33 : use, intrinsic :: iso_c_binding, only: c_loc, c_size_t
34 : use defs_abitypes, only : MPI_type
35 : use m_time, only : timab
36 : use m_bandfft_kpt, only : bandfft_kpt, bandfft_kpt_get_ikpt, bandfft_kpt_type
37 : use m_pawcprj, only : pawcprj_type
38 : use m_hamiltonian, only : gs_hamiltonian_type
39 : use m_nonlop, only : nonlop
40 : use m_getghc, only : multithreaded_getghc
41 : use m_fft, only : fourwf, fourwf_optmem
42 :
43 : #if defined HAVE_GPU_CUDA
44 : use m_manage_cuda
45 : #endif
46 :
47 : #if defined HAVE_YAKL
48 : use gator_mod
49 : #endif
50 :
51 : #if defined(HAVE_GPU_CUDA) && defined(HAVE_YAKL)
52 : use m_gpu_toolbox, only : CPU_DEVICE_ID, gpu_device_synchronize, gpu_data_prefetch_async
53 : #endif
54 :
55 : implicit none
56 :
57 : private
58 : !!***
59 :
60 : public :: prep_getghc
61 : public :: prep_nonlop
62 : public :: prep_fourwf
63 : public :: prep_wavef_sym_do
64 : public :: prep_wavef_sym_undo
65 : public :: prep_index_wavef_bandpp
66 : public :: prep_sort_wavef_spin
67 : !!***
68 :
69 : contains
70 : !!***
71 :
72 : !!****f* ABINIT/prep_getghc
73 : !! NAME
74 : !! prep_getghc
75 : !!
76 : !! FUNCTION
77 : !! this routine prepares the data to the call of getghc.
78 : !!
79 : !! INPUTS
80 : !! blocksize= size of block for FFT
81 : !! cpopt=flag defining the status of cprjin%cp(:)=<Proj_i|Cnk> scalars (see below, side effects)
82 : !! cwavef(2,npw*my_nspinor*blocksize)=planewave coefficients of wavefunction.
83 : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the hamiltonian at k
84 : !! gvnlxc=matrix elements <G|Vnonlocal+VFockACE|C>
85 : !! lambda=factor to be used when computing <G|H-lambda.S|C> - only for sij_opt=-1
86 : !! Typically lambda is the eigenvalue (or its guess)
87 : !! mpi_enreg=information about mpi parallelization
88 : !! prtvol=control print volume and debugging output
89 : !! sij_opt= -PAW ONLY- if 0, only matrix elements <G|H|C> have to be computed
90 : !! (S=overlap) if 1, matrix elements <G|S|C> have to be computed in gsc in addition to ghc
91 : !! if -1, matrix elements <G|H-lambda.S|C> have to be computed in ghc (gsc not used)
92 : !!
93 : !! OUTPUT
94 : !! gwavef=(2,npw*my_nspinor*blocksize)=matrix elements <G|H|C> (if sij_opt>=0)
95 : !! or <G|H-lambda.S|C> (if sij_opt=-1).
96 : !! swavef=(2,npw*my_nspinor*blocksize)=matrix elements <G|S|C>.
97 : !!
98 : !! SIDE EFFECTS
99 : !! ====== if gs_hamk%usepaw==1
100 : !! cwaveprj(natom,my_nspinor*bandpp)= wave functions at k projected with nl projectors
101 : !!
102 : !! SOURCE
103 :
104 59132 : subroutine prep_getghc(cwavef, gs_hamk, gvnlxc, gwavef, swavef, lambda, blocksize, &
105 59132 : mpi_enreg, prtvol, sij_opt, cpopt, cwaveprj, &
106 : already_transposed) ! optional argument
107 :
108 : !Arguments ------------------------------------
109 : !scalars
110 : integer,intent(in) :: blocksize,cpopt,prtvol,sij_opt
111 : logical, intent(in),optional :: already_transposed
112 : real(dp),intent(in) :: lambda
113 : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
114 : type(mpi_type),intent(in) :: mpi_enreg
115 : !arrays
116 : real(dp),intent(in) :: cwavef(:,:)
117 : real(dp),intent(inout) :: gvnlxc (:,:),gwavef(:,:),swavef(:,:)
118 : type(pawcprj_type), intent(inout) :: cwaveprj(:,:)
119 :
120 : !Local variables-------------------------------
121 : !scalars
122 : integer,parameter :: tim_getghc=6
123 : integer :: bandpp,bandpp_sym,idatarecv0,ier,ikpt_this_proc,iscalc,mcg,my_nspinor
124 : integer :: nbval,ndatarecv,ndatarecv_tot,ndatasend_sym,nproc_band,nproc_fft
125 : integer :: spaceComm
126 : logical :: flag_inv_sym, do_transpose, local_gvnlxc
127 : !character(len=500) :: msg
128 : !arrays
129 59132 : integer,allocatable :: index_wavef_band(:),index_wavef_send(:),index_wavef_spband(:)
130 59132 : integer,allocatable :: rdisplsloc(:),recvcountsloc(:),sdisplsloc(:),sendcountsloc(:)
131 59132 : integer,contiguous, pointer :: kg_k_gather_sym(:,:)
132 59132 : integer,contiguous, pointer :: rdispls(:),rdispls_sym(:)
133 59132 : integer,contiguous, pointer :: recvcounts(:),recvcounts_sym(:),recvcounts_sym_tot(:)
134 59132 : integer,contiguous, pointer :: sdispls(:),sdispls_sym(:)
135 59132 : integer,contiguous, pointer :: sendcounts(:),sendcounts_sym(:),sendcounts_sym_all(:)
136 59132 : integer,contiguous, pointer :: tab_proc(:)
137 : real(dp) :: tsec(2)
138 59132 : real(dp),allocatable,target :: cwavef_alltoall1(:,:), gvnlxc_alltoall1(:,:)
139 59132 : real(dp),allocatable,target :: gwavef_alltoall1(:,:), swavef_alltoall1(:,:)
140 :
141 : #if defined HAVE_GPU && defined HAVE_YAKL
142 : real(c_double), contiguous, pointer :: cwavef_alltoall2(:,:) => null()
143 : real(c_double), contiguous, pointer :: gvnlxc_alltoall2(:,:) => null()
144 : real(c_double), contiguous, pointer :: gwavef_alltoall2(:,:) => null()
145 : real(c_double), contiguous, pointer :: swavef_alltoall2(:,:) => null()
146 : #else
147 59132 : real(dp),allocatable,target :: cwavef_alltoall2(:,:)
148 59132 : real(dp),allocatable,target :: gvnlxc_alltoall2(:,:)
149 59132 : real(dp),allocatable,target :: gwavef_alltoall2(:,:)
150 59132 : real(dp),allocatable,target :: swavef_alltoall2(:,:)
151 : #endif
152 :
153 59132 : real(dp),pointer :: ewavef_alltoall_sym(:,:)
154 59132 : real(dp),pointer :: gvnlxc_alltoall_sym(:,:)
155 59132 : real(dp),pointer :: gwavef_alltoall_sym(:,:)
156 59132 : real(dp),pointer :: swavef_alltoall_sym(:,:)
157 :
158 : ! *************************************************************************
159 :
160 59132 : call timab(630,1,tsec)
161 59132 : call timab(631,3,tsec)
162 :
163 : !Some inits
164 59132 : nproc_band = mpi_enreg%nproc_band
165 59132 : nproc_fft = mpi_enreg%nproc_fft
166 59132 : bandpp = mpi_enreg%bandpp
167 59132 : my_nspinor = max(1,gs_hamk%nspinor/mpi_enreg%nproc_spinor)
168 :
169 59132 : do_transpose = .true.
170 59132 : if(present(already_transposed)) then
171 59132 : if(already_transposed) do_transpose = .false.
172 : end if
173 :
174 59132 : flag_inv_sym = (gs_hamk%istwf_k==2 .and. any(gs_hamk%ngfft(7) == [401,402,312,512]))
175 : if (flag_inv_sym) then
176 3274 : gs_hamk%istwf_k = 1
177 3274 : if (modulo(bandpp,2)==0) bandpp_sym = bandpp/2
178 3274 : if (modulo(bandpp,2)/=0) bandpp_sym = bandpp
179 : end if
180 :
181 : !Check sizes
182 59132 : mcg=2*gs_hamk%npw_fft_k*my_nspinor*bandpp
183 59132 : if (do_transpose) mcg=2*gs_hamk%npw_k*my_nspinor*blocksize
184 177396 : if (size(cwavef)<mcg) then
185 0 : ABI_BUG('wrong size for cwavef!')
186 : end if
187 177396 : if (size(gwavef)<mcg) then
188 0 : ABI_BUG('wrong size for gwavef!')
189 : end if
190 59132 : local_gvnlxc = .false.
191 177396 : if (size(gvnlxc)<=1) then
192 27896 : local_gvnlxc = .true.
193 : end if
194 177396 : if ((.not.local_gvnlxc).and.(size(gvnlxc)<mcg)) then
195 0 : ABI_BUG('wrong size for gvnlxc!')
196 : end if
197 59132 : if (sij_opt==1) then
198 75864 : if (size(swavef)<mcg) then
199 0 : ABI_BUG('wrong size for swavef!')
200 : end if
201 : end if
202 59132 : if (gs_hamk%usepaw==1.and.cpopt>=0) then
203 77808 : if (size(cwaveprj)<gs_hamk%natom*my_nspinor*bandpp) then
204 0 : ABI_BUG('wrong size for cwaveprj!')
205 : end if
206 : end if
207 :
208 : !====================================================================================
209 :
210 59132 : spaceComm=mpi_enreg%comm_fft
211 59132 : if(mpi_enreg%paral_kgb==1) spaceComm=mpi_enreg%comm_band
212 :
213 59132 : ikpt_this_proc=bandfft_kpt_get_ikpt()
214 :
215 177396 : ABI_MALLOC(sendcountsloc,(nproc_band))
216 118264 : ABI_MALLOC(sdisplsloc ,(nproc_band))
217 118264 : ABI_MALLOC(recvcountsloc,(nproc_band))
218 118264 : ABI_MALLOC(rdisplsloc ,(nproc_band))
219 :
220 59132 : recvcounts =>bandfft_kpt(ikpt_this_proc)%recvcounts(:)
221 59132 : sendcounts =>bandfft_kpt(ikpt_this_proc)%sendcounts(:)
222 59132 : rdispls =>bandfft_kpt(ikpt_this_proc)%rdispls (:)
223 59132 : sdispls =>bandfft_kpt(ikpt_this_proc)%sdispls (:)
224 59132 : ndatarecv = bandfft_kpt(ikpt_this_proc)%ndatarecv
225 :
226 59132 : if (flag_inv_sym ) then
227 3274 : idatarecv0 = bandfft_kpt(ikpt_this_proc)%idatarecv0
228 3274 : ndatarecv_tot = bandfft_kpt(ikpt_this_proc)%ndatarecv_tot
229 3274 : ndatasend_sym = bandfft_kpt(ikpt_this_proc)%ndatasend_sym
230 3274 : kg_k_gather_sym =>bandfft_kpt(ikpt_this_proc)%kg_k_gather_sym(:,:)
231 3274 : rdispls_sym =>bandfft_kpt(ikpt_this_proc)%rdispls_sym(:)
232 3274 : recvcounts_sym =>bandfft_kpt(ikpt_this_proc)%recvcounts_sym(:)
233 3274 : recvcounts_sym_tot =>bandfft_kpt(ikpt_this_proc)%recvcounts_sym_tot(:)
234 3274 : sdispls_sym =>bandfft_kpt(ikpt_this_proc)%sdispls_sym(:)
235 3274 : sendcounts_sym =>bandfft_kpt(ikpt_this_proc)%sendcounts_sym(:)
236 3274 : sendcounts_sym_all =>bandfft_kpt(ikpt_this_proc)%sendcounts_sym_all(:)
237 3274 : tab_proc =>bandfft_kpt(ikpt_this_proc)%tab_proc(:)
238 : end if
239 59132 : iscalc=(sij_opt+1)/2 ! 0 if S not calculated, 1 otherwise
240 59132 : nbval=(ndatarecv*my_nspinor*bandpp)*iscalc
241 :
242 : if ( ((.not.flag_inv_sym) .and. bandpp==1 .and. mpi_enreg%paral_spinor==0 .and. my_nspinor==2 ).or. &
243 59132 : & ((.not.flag_inv_sym) .and. bandpp>1) .or. flag_inv_sym ) then
244 130320 : ABI_MALLOC(cwavef_alltoall1,(2,ndatarecv*my_nspinor*bandpp))
245 86880 : ABI_MALLOC(gwavef_alltoall1,(2,ndatarecv*my_nspinor*bandpp))
246 86880 : ABI_MALLOC(swavef_alltoall1,(2,ndatarecv*my_nspinor*bandpp))
247 43440 : if (local_gvnlxc) then
248 27896 : ABI_MALLOC(gvnlxc_alltoall1,(0,0))
249 : else
250 31088 : ABI_MALLOC(gvnlxc_alltoall1,(2,ndatarecv*my_nspinor*bandpp))
251 : end if
252 228702600 : swavef_alltoall1(:,:)=zero
253 228702600 : cwavef_alltoall1(:,:)=zero
254 228702600 : gwavef_alltoall1(:,:)=zero
255 152784600 : if (.not.local_gvnlxc) gvnlxc_alltoall1(:,:)=zero
256 : end if
257 :
258 59132 : if(gs_hamk%gpu_option==ABI_GPU_KOKKOS) then
259 : #if defined HAVE_GPU && defined HAVE_YAKL
260 : ABI_MALLOC_MANAGED(cwavef_alltoall2,(/2,ndatarecv*my_nspinor*bandpp/))
261 : ABI_MALLOC_MANAGED(gwavef_alltoall2,(/2,ndatarecv*my_nspinor*bandpp/))
262 : ABI_MALLOC_MANAGED(swavef_alltoall2,(/2,ndatarecv*my_nspinor*bandpp/))
263 : if (local_gvnlxc) then
264 : ABI_MALLOC_MANAGED(gvnlxc_alltoall2,(/0,0/))
265 : else
266 : ABI_MALLOC_MANAGED(gvnlxc_alltoall2,(/2,ndatarecv*my_nspinor*bandpp/))
267 : end if
268 : #endif
269 : else
270 177396 : ABI_MALLOC(cwavef_alltoall2,(2,ndatarecv*my_nspinor*bandpp))
271 118264 : ABI_MALLOC(gwavef_alltoall2,(2,ndatarecv*my_nspinor*bandpp))
272 118264 : ABI_MALLOC(swavef_alltoall2,(2,ndatarecv*my_nspinor*bandpp))
273 59132 : if (local_gvnlxc) then
274 27896 : ABI_MALLOC(gvnlxc_alltoall2,(0,0))
275 : else
276 62472 : ABI_MALLOC(gvnlxc_alltoall2,(2,ndatarecv*my_nspinor*bandpp))
277 : end if
278 : end if
279 :
280 251503076 : swavef_alltoall2(:,:)=zero
281 251503076 : cwavef_alltoall2(:,:)=zero
282 251503076 : gwavef_alltoall2(:,:)=zero
283 175585076 : if (.not.local_gvnlxc) gvnlxc_alltoall2(:,:)=zero
284 :
285 204868 : recvcountsloc(:)=recvcounts(:)*2*my_nspinor*bandpp
286 204868 : rdisplsloc(:)=rdispls(:)*2*my_nspinor*bandpp
287 204868 : sendcountsloc(:)=sendcounts(:)*2*my_nspinor
288 204868 : sdisplsloc(:)=sdispls(:)*2*my_nspinor
289 59132 : call timab(631,2,tsec)
290 :
291 59132 : if(do_transpose) then
292 30900 : call timab(545,3,tsec)
293 : if ( ((.not.flag_inv_sym) .and. bandpp==1 .and. mpi_enreg%paral_spinor==0 .and. my_nspinor==2 ).or. &
294 30900 : & ((.not.flag_inv_sym) .and. bandpp>1) .or. flag_inv_sym ) then
295 : call xmpi_alltoallv(cwavef,sendcountsloc,sdisplsloc,cwavef_alltoall1,&
296 15208 : & recvcountsloc,rdisplsloc,spaceComm,ier)
297 : else
298 : call xmpi_alltoallv(cwavef,sendcountsloc,sdisplsloc,cwavef_alltoall2,&
299 15692 : & recvcountsloc,rdisplsloc,spaceComm,ier)
300 : end if
301 30900 : call timab(545,2,tsec)
302 : else
303 : ! Here, we cheat, and use DCOPY to bypass some compiler's overzealous bound-checking
304 : ! (ndatarecv*my_nspinor*bandpp might be greater than the declared size of cwavef)
305 28232 : call DCOPY(2*ndatarecv*my_nspinor*bandpp, cwavef, 1, cwavef_alltoall2, 1)
306 : end if
307 :
308 : !====================================================================
309 59132 : if ((.not.(flag_inv_sym)) .and. (bandpp==1)) then
310 15692 : if (do_transpose .and. mpi_enreg%paral_spinor==0.and.my_nspinor==2)then
311 0 : call timab(632,3,tsec)
312 : ! Sort to have all ispinor=1 first, then all ispinor=2
313 0 : call prep_sort_wavef_spin(nproc_band,my_nspinor,ndatarecv,recvcounts,rdispls,index_wavef_spband)
314 0 : cwavef_alltoall2(:,:)=cwavef_alltoall1(:,index_wavef_spband)
315 0 : call timab(632,2,tsec)
316 : end if
317 :
318 15692 : call timab(635,3,tsec)
319 : call multithreaded_getghc(cpopt,cwavef_alltoall2,cwaveprj,gwavef_alltoall2,swavef_alltoall2(:,1:nbval),&
320 15692 : & gs_hamk,gvnlxc_alltoall2,lambda,mpi_enreg,1,prtvol,sij_opt,tim_getghc,0)
321 15692 : call timab(635,2,tsec)
322 :
323 15692 : if (do_transpose .and. mpi_enreg%paral_spinor==0.and.my_nspinor==2)then
324 0 : call timab(634,3,tsec)
325 0 : gwavef_alltoall1(:,index_wavef_spband)=gwavef_alltoall2(:,:)
326 0 : if (sij_opt==1) swavef_alltoall1(:,index_wavef_spband)=swavef_alltoall2(:,:)
327 0 : if (.not.local_gvnlxc) gvnlxc_alltoall1(:,index_wavef_spband)=gvnlxc_alltoall2(:,:)
328 0 : ABI_FREE(index_wavef_spband)
329 0 : call timab(634,2,tsec)
330 : end if
331 :
332 43440 : else if ((.not.(flag_inv_sym)) .and. (bandpp>1)) then
333 : ! -------------------------------------------------------------
334 : ! Computation of the index to class the waves functions below bandpp
335 : ! -------------------------------------------------------------
336 :
337 40166 : if(do_transpose) then
338 13590 : call timab(632,3,tsec)
339 : call prep_index_wavef_bandpp(nproc_band,bandpp,&
340 13590 : & my_nspinor,ndatarecv, recvcounts,rdispls, index_wavef_band)
341 : ! -------------------------------------------------------
342 : ! Sorting of the waves functions below bandpp
343 : ! -------------------------------------------------------
344 125187702 : cwavef_alltoall2(:,:) = cwavef_alltoall1(:,index_wavef_band)
345 13590 : call timab(632,2,tsec)
346 : end if
347 :
348 : ! ----------------------
349 : ! Fourier transformation
350 : ! ----------------------
351 40166 : call timab(636,3,tsec)
352 : call multithreaded_getghc(cpopt,cwavef_alltoall2,cwaveprj,gwavef_alltoall2,swavef_alltoall2,gs_hamk,&
353 40166 : & gvnlxc_alltoall2,lambda,mpi_enreg,bandpp,prtvol,sij_opt,tim_getghc,0)
354 40166 : call timab(636,2,tsec)
355 :
356 : ! -----------------------------------------------------
357 : ! Sorting of waves functions below the processors
358 : ! -----------------------------------------------------
359 40166 : if(do_transpose) then
360 13590 : call timab(634,3,tsec)
361 125187702 : gwavef_alltoall1(:,index_wavef_band) = gwavef_alltoall2(:,:)
362 15165318 : if (sij_opt==1) swavef_alltoall1(:,index_wavef_band) = swavef_alltoall2(:,:)
363 125187702 : if (.not.local_gvnlxc) gvnlxc_alltoall1(:,index_wavef_band) = gvnlxc_alltoall2(:,:)
364 13590 : ABI_FREE(index_wavef_band)
365 13590 : call timab(634,2,tsec)
366 : end if
367 :
368 :
369 3274 : else if (flag_inv_sym) then
370 :
371 : ! -------------------------------------------------------------
372 : ! Computation of the index to class the waves functions below bandpp
373 : ! -------------------------------------------------------------
374 3274 : if(do_transpose) then
375 1618 : call timab(632,3,tsec)
376 : call prep_index_wavef_bandpp(nproc_band,bandpp,&
377 : & my_nspinor,ndatarecv,&
378 : & recvcounts,rdispls,&
379 1618 : & index_wavef_band)
380 :
381 : ! -------------------------------------------------------
382 : ! Sorting the wave functions below bandpp
383 : ! -------------------------------------------------------
384 26785450 : cwavef_alltoall2(:,:) = cwavef_alltoall1(:,index_wavef_band)
385 : end if
386 :
387 : ! ------------------------------------------------------------
388 : ! We associate the waves functions by two
389 : ! ------------------------------------------------------------
390 : call prep_wavef_sym_do(mpi_enreg,bandpp,my_nspinor,&
391 : & ndatarecv,&
392 : & ndatarecv_tot,ndatasend_sym,tab_proc,&
393 : & cwavef_alltoall2,&
394 : & sendcounts_sym,sdispls_sym,&
395 : & recvcounts_sym,rdispls_sym,&
396 : & ewavef_alltoall_sym,&
397 3274 : & index_wavef_send)
398 :
399 : ! ------------------------------------------------------------
400 : ! Allocation
401 : ! ------------------------------------------------------------
402 9822 : ABI_MALLOC(gwavef_alltoall_sym,(2,ndatarecv_tot*bandpp_sym))
403 9822 : ABI_MALLOC(swavef_alltoall_sym,(2,(ndatarecv_tot*bandpp_sym)*iscalc))
404 3274 : if (local_gvnlxc) then
405 1656 : ABI_MALLOC(gvnlxc_alltoall_sym ,(0,0))
406 : else
407 3236 : ABI_MALLOC(gvnlxc_alltoall_sym ,(2,ndatarecv_tot*bandpp_sym))
408 : end if
409 27990616 : gwavef_alltoall_sym(:,:)=zero
410 665260 : swavef_alltoall_sym(:,:)=zero
411 26778514 : if (.not.local_gvnlxc) gvnlxc_alltoall_sym(:,:)=zero
412 :
413 3274 : call timab(632,2,tsec)
414 :
415 : ! ------------------------------------------------------------
416 : ! Fourier calculation
417 : ! ------------------------------------------------------------
418 3274 : call timab(637,3,tsec)
419 : call multithreaded_getghc(cpopt,ewavef_alltoall_sym,cwaveprj,gwavef_alltoall_sym,swavef_alltoall_sym,gs_hamk,&
420 : & gvnlxc_alltoall_sym,lambda,mpi_enreg,bandpp_sym,prtvol,sij_opt,tim_getghc,1,&
421 3274 : & kg_fft_k=kg_k_gather_sym,filter_dilatmx_loc=.false.)
422 3274 : call timab(637,2,tsec)
423 :
424 3274 : call timab(633,3,tsec)
425 :
426 : ! ------------------------------------------------------------
427 : ! We dissociate each wave function in two waves functions
428 : ! gwavef is classed below of bandpp
429 : ! ------------------------------------------------------------
430 : call prep_wavef_sym_undo(mpi_enreg,bandpp,my_nspinor,&
431 : & ndatarecv,&
432 : & ndatarecv_tot,ndatasend_sym,idatarecv0,&
433 : & gwavef_alltoall2,&
434 : & sendcounts_sym,sdispls_sym,&
435 : & recvcounts_sym,rdispls_sym,&
436 : & gwavef_alltoall_sym,&
437 3274 : & index_wavef_send)
438 3274 : if (sij_opt==1)then
439 : call prep_wavef_sym_undo(mpi_enreg,bandpp,my_nspinor,&
440 : & ndatarecv,&
441 : & ndatarecv_tot,ndatasend_sym,idatarecv0,&
442 : & swavef_alltoall2,&
443 : & sendcounts_sym,sdispls_sym,&
444 : & recvcounts_sym,rdispls_sym,&
445 : & swavef_alltoall_sym,&
446 1062 : & index_wavef_send)
447 : end if
448 3274 : if (.not.local_gvnlxc) call prep_wavef_sym_undo(mpi_enreg,bandpp,my_nspinor,&
449 : & ndatarecv,&
450 : & ndatarecv_tot,ndatasend_sym,idatarecv0,&
451 : & gvnlxc_alltoall2,&
452 : & sendcounts_sym,sdispls_sym,&
453 : & recvcounts_sym,rdispls_sym,&
454 : & gvnlxc_alltoall_sym,&
455 1618 : & index_wavef_send)
456 :
457 3274 : ABI_FREE(ewavef_alltoall_sym)
458 3274 : ABI_FREE(index_wavef_send)
459 3274 : ABI_FREE(gwavef_alltoall_sym)
460 3274 : ABI_FREE(swavef_alltoall_sym)
461 3274 : ABI_FREE(gvnlxc_alltoall_sym)
462 :
463 : ! -------------------------------------------
464 : ! We call getghc to calculate the nl matrix elements.
465 : ! --------------------------------------------
466 3274 : gs_hamk%istwf_k=2
467 : !!write(std_out,*)"Setting iswfk_k to 2"
468 :
469 3274 : call timab(633,2,tsec)
470 :
471 3274 : call timab(638,3,tsec)
472 : call multithreaded_getghc(cpopt,cwavef_alltoall2,cwaveprj,gwavef_alltoall2,swavef_alltoall2,gs_hamk,&
473 3274 : & gvnlxc_alltoall2,lambda,mpi_enreg,bandpp,prtvol,sij_opt,tim_getghc,2)
474 3274 : call timab(638,2,tsec)
475 :
476 3274 : call timab(634,3,tsec)
477 :
478 3274 : gs_hamk%istwf_k=1
479 :
480 : ! -------------------------------------------------------
481 : ! Sorting the wave functions below the processors
482 : ! -------------------------------------------------------
483 3274 : if(do_transpose) then
484 : ! cwavef_alltoall(:,index_wavef_band) = cwavef_alltoall(:,:) ! NOT NEEDED
485 26785450 : gwavef_alltoall1(:,index_wavef_band) = gwavef_alltoall2(:,:)
486 374842 : if (sij_opt==1) swavef_alltoall1(:,index_wavef_band) = swavef_alltoall2(:,:)
487 26785450 : if (.not.local_gvnlxc) gvnlxc_alltoall1(:,index_wavef_band) = gvnlxc_alltoall2(:,:)
488 1618 : ABI_FREE(index_wavef_band)
489 1618 : call timab(634,2,tsec)
490 : end if
491 :
492 : end if
493 : !====================================================================
494 :
495 30900 : if(do_transpose) then
496 :
497 30900 : call timab(545,3,tsec)
498 : if ( ((.not.flag_inv_sym) .and. bandpp==1 .and. mpi_enreg%paral_spinor==0 .and. my_nspinor==2 ).or. &
499 30900 : & ((.not.flag_inv_sym) .and. bandpp>1) .or. flag_inv_sym ) then
500 15208 : if (sij_opt==1) then
501 : call xmpi_alltoallv(swavef_alltoall1,recvcountsloc,rdisplsloc,swavef,&
502 9088 : & sendcountsloc,sdisplsloc,spaceComm,ier)
503 : end if
504 15208 : if (.not.local_gvnlxc) call xmpi_alltoallv(gvnlxc_alltoall1,recvcountsloc,rdisplsloc,gvnlxc,&
505 15208 : & sendcountsloc,sdisplsloc,spaceComm,ier)
506 : call xmpi_alltoallv(gwavef_alltoall1,recvcountsloc,rdisplsloc,gwavef,&
507 15208 : & sendcountsloc,sdisplsloc,spaceComm,ier)
508 : else
509 15692 : if (sij_opt==1) then
510 : call xmpi_alltoallv(swavef_alltoall2,recvcountsloc,rdisplsloc,swavef,&
511 15692 : & sendcountsloc,sdisplsloc,spaceComm,ier)
512 : end if
513 15692 : if (.not.local_gvnlxc) call xmpi_alltoallv(gvnlxc_alltoall2,recvcountsloc,rdisplsloc,gvnlxc,&
514 15692 : & sendcountsloc,sdisplsloc,spaceComm,ier)
515 : call xmpi_alltoallv(gwavef_alltoall2,recvcountsloc,rdisplsloc,gwavef,&
516 15692 : & sendcountsloc,sdisplsloc,spaceComm,ier)
517 : end if
518 :
519 30900 : call timab(545,2,tsec)
520 : else
521 28232 : if(sij_opt == 1) then
522 508 : call DCOPY(2*ndatarecv*my_nspinor*bandpp, swavef_alltoall2, 1, swavef, 1)
523 : end if
524 28232 : if (.not.local_gvnlxc) call DCOPY(2*ndatarecv*my_nspinor*bandpp, gvnlxc_alltoall2, 1, gvnlxc, 1)
525 28232 : call DCOPY(2*ndatarecv*my_nspinor*bandpp, gwavef_alltoall2, 1, gwavef, 1)
526 : end if
527 :
528 : !====================================================================
529 59132 : if (flag_inv_sym) then
530 3274 : gs_hamk%istwf_k = 2
531 : end if
532 : !====================================================================
533 59132 : ABI_FREE(sendcountsloc)
534 59132 : ABI_FREE(sdisplsloc)
535 59132 : ABI_FREE(recvcountsloc)
536 59132 : ABI_FREE(rdisplsloc)
537 :
538 59132 : if(gs_hamk%gpu_option==ABI_GPU_KOKKOS) then
539 : #if defined HAVE_GPU && defined HAVE_YAKL
540 : ABI_FREE_MANAGED(cwavef_alltoall2)
541 : ABI_FREE_MANAGED(gwavef_alltoall2)
542 : ABI_FREE_MANAGED(gvnlxc_alltoall2)
543 : ABI_FREE_MANAGED(swavef_alltoall2)
544 : #endif
545 : else
546 59132 : ABI_FREE(cwavef_alltoall2)
547 59132 : ABI_FREE(gwavef_alltoall2)
548 59132 : ABI_FREE(gvnlxc_alltoall2)
549 59132 : ABI_FREE(swavef_alltoall2)
550 : end if
551 :
552 : if ( ((.not.flag_inv_sym) .and. bandpp==1 .and. mpi_enreg%paral_spinor==0 .and. my_nspinor==2 ).or. &
553 59132 : & ((.not.flag_inv_sym) .and. bandpp>1) .or. flag_inv_sym ) then
554 43440 : ABI_FREE(cwavef_alltoall1)
555 43440 : ABI_FREE(gwavef_alltoall1)
556 43440 : ABI_FREE(gvnlxc_alltoall1)
557 43440 : ABI_FREE(swavef_alltoall1)
558 : end if
559 :
560 59132 : call timab(630,2,tsec)
561 :
562 118264 : end subroutine prep_getghc
563 : !!***
564 :
565 : !!****f* abinit/prep_nonlop
566 : !! NAME
567 : !! prep_nonlop
568 : !!
569 : !! FUNCTION
570 : !! this routine prepares the data to the call of nonlop.
571 : !!
572 : !! INPUTS
573 : !! choice: chooses possible output:
574 : !! choice=1 => a non-local energy contribution
575 : !! =2 => a gradient with respect to atomic position(s)
576 : !! =3 => a gradient with respect to strain(s)
577 : !! =23=> a gradient with respect to atm. pos. and strain(s)
578 : !! =4 => a 2nd derivative with respect to atomic pos.
579 : !! =24=> a gradient and 2nd derivative with respect to atomic pos.
580 : !! =5 => a gradient with respect to k wavevector
581 : !! =6 => 2nd derivatives with respect to strain and atm. pos.
582 : !! =7 => no operator, just projections
583 : !! blocksize= size of block for FFT
584 : !! cpopt=flag defining the status of cwaveprj=<Proj_i|Cnk> scalars (see below, side effects)
585 : !! cwavef(2,npw*my_nspinor*blocksize)=planewave coefficients of wavefunction.
586 : !! gvnlxc=matrix elements <G|Vnonlocal+VFockACE|C>
587 : !! hamk <type(gs_hamiltonian_type)>=data defining the Hamiltonian at a given k (NL part involved here)
588 : !! idir=direction of the - atom to be moved in the case (choice=2,signs=2),
589 : !! - k point direction in the case (choice=5,signs=2)
590 : !! - strain component (1:6) in the case (choice=2,signs=2) or (choice=6,signs=1)
591 : !! lambdablock(blocksize)=factor to be used when computing (Vln-lambda.S) - only for paw_opt=2
592 : !! mpi_enreg=information about mpi parallelization
593 : !! nnlout=dimension of enlout (when signs=1):
594 : !! ntypat=number of types of atoms in cell
595 : !! paw_opt= define the nonlocal operator concerned with
596 : !! signs= if 1, get contracted elements (energy, forces, stress, ...)
597 : !! if 2, applies the non-local operator to a function in reciprocal space
598 : !! tim_nonlop=timing code of the calling routine (can be set to 0 if not attributed)
599 : !! vectproj(2,nprojs,my_nspinor*ndat)=Optional, vector to be used instead of cprjin%cp when provided
600 : !!
601 : !! OUTPUT
602 : !! ==== if (signs==1) ====
603 : !! enlout_block(nnlout)=
604 : !! if paw_opt==0, 1 or 2: contribution of this block of states to the nl part of various properties
605 : !! if paw_opt==3: contribution of this block of states to <c|S|c> (where S=overlap when PAW)
606 : !! ==== if (signs==2) ====
607 : !! if paw_opt==0, 1, 2 or 4:
608 : !! gvnlc(2,my_nspinor*npw)=result of the application of the nl operator
609 : !! or one of its derivative to the input vect.
610 : !! if paw_opt==3 or 4:
611 : !! gsc(2,my_nspinor*npw*(paw_opt/3))=result of the aplication of (I+S)
612 : !! to the input vect. (where S=overlap when PAW)
613 : !!
614 : !! SIDE EFFECTS
615 : !! ==== ONLY IF useylm=1
616 : !! cwaveprj(natom,my_nspinor) <type(pawcprj_type)>=projected input wave function |c> on non-local projector
617 : !! =<p_lmn|c> and derivatives
618 : !! Treatment depends on cpopt parameter:
619 : !! if cpopt=-1, <p_lmn|in> (and derivatives)
620 : !! have to be computed (and not saved)
621 : !! if cpopt= 0, <p_lmn|in> have to be computed and saved
622 : !! derivatives are eventually computed but not saved
623 : !! if cpopt= 1, <p_lmn|in> and first derivatives have to be computed and saved
624 : !! other derivatives are eventually computed but not saved
625 : !! if cpopt= 2 <p_lmn|in> are already in memory;
626 : !! only derivatives are computed here and not saved
627 : !! (if useylm=0, should have cpopt=-1)
628 : !!
629 : !! NOTES
630 : !! cprj (as well as cg) is distributed over band processors.
631 : !! Only the mod((iband-1)/mpi_enreg%bandpp,mpi_enreg%nproc_band) projected WFs are stored on each proc.
632 : !!
633 : !! SOURCE
634 :
635 264842 : subroutine prep_nonlop(choice,cpopt,cwaveprj,enlout_block,hamk,idir,lambdablock,&
636 264842 : blocksize,mpi_enreg,nnlout,paw_opt,signs,gsc, tim_nonlop,cwavef,gvnlc, &
637 264842 : already_transposed,gpu_option,vectproj,cwavef_tr) ! optional
638 :
639 : !Arguments ------------------------------------
640 : integer, intent(in) :: blocksize,choice,cpopt,idir,signs,nnlout,paw_opt
641 : logical,optional,intent(in) :: already_transposed
642 : integer,optional,intent(in) :: gpu_option
643 : real(dp), intent(in) :: lambdablock(blocksize)
644 : real(dp), intent(out) , target :: enlout_block(nnlout*blocksize),gvnlc(:,:),gsc(:,:)
645 : real(dp), intent(inout), target :: cwavef(:,:)
646 : real(dp),intent(inout), pointer,optional :: cwavef_tr(:,:)
647 : real(dp),contiguous, optional,intent(inout) :: vectproj(:,:,:)
648 : type(gs_hamiltonian_type),intent(in) :: hamk
649 : type(mpi_type),intent(in) :: mpi_enreg
650 : type(pawcprj_type),intent(inout) :: cwaveprj(:,:)
651 :
652 : !Local variables-------------------------------
653 : !scalars
654 : integer :: bandpp,ier,ikpt_this_proc,my_nspinor,ndatarecv,nproc_band,npw,nspinortot
655 : integer :: spaceComm=0,tim_nonlop
656 : logical :: do_transpose,transfer_cwavef
657 : integer :: l_gpu_option
658 : #ifdef HAVE_OPENMP_OFFLOAD
659 : integer :: ipw,ind,iibandpp
660 : #endif
661 : !character(len=500) :: msg
662 : !arrays
663 264842 : integer, allocatable :: index_wavef_band(:)
664 264842 : integer, allocatable :: rdisplsloc(:),recvcountsloc(:),sdisplsloc(:),sendcountsloc(:)
665 264842 : integer,contiguous, pointer :: rdispls(:),recvcounts(:),sdispls(:),sendcounts(:)
666 529684 : real(dp) :: lambda_nonlop(mpi_enreg%bandpp)
667 : real(dp) :: tsec(2)
668 :
669 : #if defined HAVE_GPU && defined HAVE_YAKL
670 : real(c_double), contiguous, pointer :: cwavef_alltoall2(:,:) => null()
671 : real(c_double), contiguous, pointer :: gvnlc_alltoall2(:,:) => null()
672 : real(c_double), contiguous, pointer :: gsc_alltoall2(:,:) => null()
673 : integer(kind=C_SIZE_T) :: cwavef_alltoall2_size
674 : integer(kind=C_SIZE_T) :: gvnlc_alltoall2_size
675 : integer(kind=C_SIZE_T) :: gsc_alltoall2_size
676 : #else
677 264842 : real(dp), pointer :: cwavef_alltoall2(:,:)
678 264842 : real(dp), allocatable :: gvnlc_alltoall2(:,:)
679 264842 : real(dp), allocatable :: gsc_alltoall2(:,:)
680 : #endif
681 :
682 264842 : real(dp), allocatable :: cwavef_alltoall1(:,:)
683 264842 : real(dp), allocatable :: gvnlc_alltoall1(:,:)
684 264842 : real(dp), allocatable :: gsc_alltoall1(:,:)
685 264842 : real(dp), allocatable :: enlout(:)
686 :
687 : #if defined HAVE_GPU && defined HAVE_YAKL
688 : ! this buffer is necessary to avoid mixing "managed memory" buffer with "regular memory" buffer in MPI calls
689 : ! Just to be clear:
690 : ! - managed memory means memory allocated using ABI_MALLOC_MANAGED
691 : ! - regular memory means memory allocated using either ABI_MALLOC or ABI_MALLOC_CUDA
692 : !
693 : ! here we chose to use a GPU buffer, would it be better to use a CPU buffer ? To be checked.
694 : !real(dp), allocatable :: cwavef_mpi(:,:)
695 : type(c_ptr) :: cwavef_mpi_c
696 : real(c_double),pointer :: cwavef_mpi(:,:)
697 : #endif
698 :
699 : ! *************************************************************************
700 :
701 : DBG_ENTER('COLL')
702 :
703 264842 : call timab(570,1,tsec)
704 :
705 264842 : do_transpose = .true.
706 264842 : bandpp = mpi_enreg%bandpp
707 264842 : if(present(already_transposed)) then
708 264842 : if(already_transposed) then
709 124920 : do_transpose = .false.
710 124920 : bandpp = blocksize
711 : end if
712 : end if
713 :
714 264842 : l_gpu_option=ABI_GPU_DISABLED
715 264842 : if (present(gpu_option)) then
716 132454 : l_gpu_option = gpu_option
717 : end if
718 :
719 264842 : nproc_band = mpi_enreg%nproc_band
720 :
721 264842 : spaceComm=mpi_enreg%comm_fft
722 264842 : if(mpi_enreg%paral_kgb==1) spaceComm=mpi_enreg%comm_band
723 264842 : my_nspinor=max(1,hamk%nspinor/mpi_enreg%nproc_spinor)
724 264842 : nspinortot=hamk%nspinor
725 :
726 : !Check sizes
727 264842 : npw=hamk%npw_k;if (.not.do_transpose) npw=hamk%npw_fft_k
728 794526 : if (size(cwavef)/=2*npw*my_nspinor*blocksize) then
729 0 : ABI_BUG('Incorrect size for cwavef!')
730 : end if
731 264842 : if(choice/=0.and.signs==2) then
732 62460 : if (paw_opt/=3) then
733 0 : if (size(gvnlc)/=2*npw*my_nspinor*blocksize) then
734 0 : ABI_BUG('Incorrect size for gvnlc!')
735 : end if
736 : end if
737 62460 : if(paw_opt>=3) then
738 187380 : if (size(gsc)/=2*npw*my_nspinor*blocksize) then
739 0 : ABI_BUG('Incorrect size for gsc!')
740 : end if
741 : end if
742 : end if
743 264842 : if(cpopt>=0.and. .not. present(vectproj)) then
744 226404 : if (size(cwaveprj)/=hamk%natom*my_nspinor*bandpp) then
745 0 : ABI_BUG('Incorrect size for cwaveprj!')
746 : end if
747 : end if
748 :
749 264842 : transfer_cwavef=.false.
750 : #ifdef HAVE_OPENMP_OFFLOAD
751 : if(.not. xomp_target_is_present(c_loc(cwavef)) .and. hamk%gpu_option==ABI_GPU_OPENMP) then
752 : transfer_cwavef=.true.
753 : end if
754 : !$OMP TARGET ENTER DATA MAP(to:cwavef) IF(transfer_cwavef)
755 : #endif
756 :
757 794526 : ABI_MALLOC(sendcountsloc,(nproc_band))
758 529684 : ABI_MALLOC(sdisplsloc ,(nproc_band))
759 529684 : ABI_MALLOC(recvcountsloc,(nproc_band))
760 529684 : ABI_MALLOC(rdisplsloc ,(nproc_band))
761 :
762 264842 : ikpt_this_proc=bandfft_kpt_get_ikpt()
763 :
764 264842 : recvcounts => bandfft_kpt(ikpt_this_proc)%recvcounts(:)
765 264842 : sendcounts => bandfft_kpt(ikpt_this_proc)%sendcounts(:)
766 264842 : rdispls => bandfft_kpt(ikpt_this_proc)%rdispls (:)
767 264842 : sdispls => bandfft_kpt(ikpt_this_proc)%sdispls (:)
768 264842 : ndatarecv = bandfft_kpt(ikpt_this_proc)%ndatarecv
769 :
770 264842 : if(hamk%gpu_option==ABI_GPU_KOKKOS) then
771 : #if defined HAVE_GPU && defined HAVE_YAKL
772 : ABI_MALLOC_MANAGED(cwavef_alltoall2, (/2,ndatarecv*my_nspinor*bandpp/))
773 : cwavef_alltoall2_size = 2*ndatarecv*my_nspinor*bandpp*dp
774 :
775 : if (paw_opt >= 0 .and. paw_opt < 3) then
776 : gsc_alltoall2 => null()
777 : gsc_alltoall2_size = 0
778 : else
779 : ABI_MALLOC_MANAGED(gsc_alltoall2, (/2,ndatarecv*my_nspinor*(paw_opt/3)*bandpp/))
780 : gsc_alltoall2_size = 2*ndatarecv*my_nspinor*(paw_opt/3)*bandpp*dp
781 : endif
782 :
783 : ABI_MALLOC_MANAGED(gvnlc_alltoall2, (/2,ndatarecv*my_nspinor*bandpp/))
784 : gvnlc_alltoall2_size = 2*ndatarecv*my_nspinor*bandpp*dp
785 : #endif
786 : else
787 264842 : if(present(cwavef_tr)) then
788 192 : if(any(shape(cwavef_tr)/=(/2,ndatarecv*my_nspinor*bandpp/))) then
789 0 : ABI_BUG('cwavef_tr does not have the correct shape')
790 : endif
791 64 : cwavef_alltoall2 => cwavef_tr
792 : else
793 794334 : ABI_MALLOC(cwavef_alltoall2, (2,ndatarecv*my_nspinor*bandpp))
794 : endif
795 794526 : ABI_MALLOC(gsc_alltoall2, (2,ndatarecv*my_nspinor*(paw_opt/3)*bandpp))
796 794526 : ABI_MALLOC(gvnlc_alltoall2, (2,ndatarecv*my_nspinor*bandpp))
797 : end if
798 :
799 : #ifdef HAVE_OPENMP_OFFLOAD
800 : !$OMP TARGET ENTER DATA MAP(alloc:cwavef_alltoall2) IF(hamk%gpu_option==ABI_GPU_OPENMP)
801 : #endif
802 :
803 264842 : if(do_transpose .and. (bandpp/=1 .or. (bandpp==1 .and. mpi_enreg%paral_spinor==0.and.nspinortot==2)))then
804 61986 : ABI_MALLOC(cwavef_alltoall1,(2,ndatarecv*my_nspinor*bandpp))
805 : #ifdef HAVE_OPENMP_OFFLOAD
806 : !$OMP TARGET ENTER DATA MAP(alloc:cwavef_alltoall1) IF(hamk%gpu_option==ABI_GPU_OPENMP)
807 : #endif
808 20662 : if(signs==2)then
809 0 : if (paw_opt/=3) then
810 0 : ABI_MALLOC(gvnlc_alltoall1,(2,ndatarecv*my_nspinor*bandpp))
811 : end if
812 0 : if (paw_opt==3.or.paw_opt==4) then
813 0 : ABI_MALLOC(gsc_alltoall1,(2,ndatarecv*my_nspinor*bandpp))
814 : end if
815 : end if
816 : end if
817 :
818 794526 : ABI_MALLOC(enlout,(nnlout*bandpp))
819 1348482 : enlout = zero
820 :
821 923600 : recvcountsloc(:)=recvcounts(:)*2*my_nspinor*bandpp
822 923600 : rdisplsloc(:)=rdispls(:)*2*my_nspinor*bandpp
823 923600 : sendcountsloc(:)=sendcounts(:)*2*my_nspinor
824 923600 : sdisplsloc(:)=sdispls(:)*2*my_nspinor
825 :
826 264842 : if(do_transpose) then
827 139922 : call timab(581,1,tsec)
828 139922 : if (bandpp/=1 .or. (bandpp==1 .and. mpi_enreg%paral_spinor==0.and.nspinortot==2)) then
829 20662 : if (l_gpu_option == ABI_GPU_KOKKOS) then
830 : #if defined HAVE_GPU && defined HAVE_YAKL
831 : ABI_MALLOC_CUDA(cwavef_mpi_c, INT(2, c_size_t) * npw * my_nspinor * blocksize * dp)
832 : call c_f_pointer(cwavef_mpi_c, cwavef_mpi, (/2, npw * my_nspinor * blocksize/))
833 :
834 : ! use cwavef_mpi instead of cwavef (don't use managed memory in MPI calls)
835 : call copy_gpu_to_gpu(cwavef_mpi_c, C_LOC(cwavef), INT(2, c_size_t) * npw * my_nspinor * blocksize * dp)
836 :
837 : call xmpi_alltoallv(cwavef_mpi,sendcountsloc,sdisplsloc,cwavef_alltoall1,&
838 : & recvcountsloc,rdisplsloc,spaceComm,ier)
839 :
840 : ABI_FREE_CUDA(cwavef_mpi_c)
841 : #endif
842 : else
843 : call xmpi_alltoallv(cwavef,sendcountsloc,sdisplsloc,cwavef_alltoall1,&
844 20662 : & recvcountsloc,rdisplsloc,spaceComm,ier,use_omp_map=(hamk%gpu_option==ABI_GPU_OPENMP))
845 : end if
846 :
847 :
848 : else
849 : call xmpi_alltoallv(cwavef,sendcountsloc,sdisplsloc,cwavef_alltoall2,&
850 119260 : & recvcountsloc,rdisplsloc,spaceComm,ier,use_omp_map=(hamk%gpu_option==ABI_GPU_OPENMP))
851 : end if
852 139922 : call timab(581,2,tsec)
853 : else
854 : ! Here, we cheat, and use DCOPY to bypass some compiler's overzealous bound-checking
855 : ! (ndatarecv*my_nspinor*bandpp might be greater than the declared size of cwavef)
856 124920 : if (l_gpu_option == ABI_GPU_KOKKOS) then
857 : #if defined(HAVE_GPU_CUDA) && defined(HAVE_KOKKOS)
858 : call copy_gpu_to_gpu(C_LOC(cwavef_alltoall2), C_LOC(cwavef), INT(2, c_size_t) * ndatarecv * my_nspinor * bandpp * dp)
859 : #endif
860 124920 : else if (hamk%gpu_option == ABI_GPU_OPENMP) then
861 0 : call gpu_copy(cwavef_alltoall2, cwavef, int(2,c_size_t)*ndatarecv*my_nspinor*bandpp)
862 : else
863 124920 : call DCOPY(2*ndatarecv*my_nspinor*bandpp,cwavef,1,cwavef_alltoall2,1)
864 : end if
865 : end if
866 :
867 : #ifdef HAVE_OPENMP_OFFLOAD
868 : !$OMP TARGET EXIT DATA MAP(delete:cwavef) IF(transfer_cwavef)
869 : #endif
870 :
871 : !=====================================================================
872 264842 : if (bandpp==1) then
873 :
874 :
875 127588 : if (do_transpose .and. mpi_enreg%paral_spinor==0.and.nspinortot==2) then !Sort WF by spin
876 7368 : call prep_sort_wavef_spin(nproc_band,my_nspinor,ndatarecv,recvcounts,rdispls,index_wavef_band)
877 7368 : if(hamk%gpu_option==ABI_GPU_OPENMP) then
878 : #ifdef HAVE_OPENMP_OFFLOAD
879 : !$OMP TARGET TEAMS DISTRIBUTE &
880 : !$OMP& PRIVATE(iibandpp) MAP(to:cwavef_alltoall1,cwavef_alltoall2,index_wavef_band)
881 : do iibandpp=1,bandpp*my_nspinor
882 : !$OMP PARALLEL DO PRIVATE(ind,ipw)
883 : do ipw = 1 ,ndatarecv
884 : ind=index_wavef_band(ipw + ndatarecv*(iibandpp-1))
885 : cwavef_alltoall2(1,ipw + ndatarecv*(iibandpp-1)) = cwavef_alltoall1(1,ind)
886 : cwavef_alltoall2(2,ipw + ndatarecv*(iibandpp-1)) = cwavef_alltoall1(2,ind)
887 : end do
888 : end do
889 : #endif
890 : else
891 6364632 : cwavef_alltoall2(:, :) = cwavef_alltoall1(:,index_wavef_band)
892 : end if
893 : end if
894 :
895 127588 : if (paw_opt==2) then
896 69568 : lambda_nonlop(1)=lambdablock(mpi_enreg%me_band+1)
897 : end if
898 : call nonlop(choice,cpopt,cwaveprj,enlout,hamk,idir,lambda_nonlop,mpi_enreg,1,nnlout,paw_opt,&
899 254216 : & signs,gsc_alltoall2,tim_nonlop,cwavef_alltoall2,gvnlc_alltoall2,vectproj=vectproj)
900 : #if defined(HAVE_GPU_CUDA) && defined(HAVE_YAKL)
901 : !call gpu_device_synchronize()
902 : !call gpu_data_prefetch_async_f(C_LOC(cwavef_alltoall2), cwavef_alltoall2_size, CPU_DEVICE_ID)
903 : !call gpu_data_prefetch_async_f(C_LOC(gvnlc_alltoall2), gvnlc_alltoall2_size, CPU_DEVICE_ID)
904 : !call gpu_data_prefetch_async_f(C_LOC(gsc_alltoall2), gsc_alltoall2_size, CPU_DEVICE_ID)
905 : #endif
906 :
907 127588 : if (do_transpose .and. mpi_enreg%paral_spinor == 0 .and. nspinortot==2.and.signs==2) then
908 0 : if (paw_opt/=3) gvnlc_alltoall1(:,index_wavef_band)=gvnlc_alltoall2(:,:)
909 0 : if (paw_opt==3.or.paw_opt==4) gsc_alltoall1(:,index_wavef_band)=gsc_alltoall2(:,:)
910 : end if
911 :
912 : else ! bandpp/=1
913 :
914 : ! -------------------------------------------------------------
915 : ! Computation of the index used to sort the waves functions below bandpp
916 : ! -------------------------------------------------------------
917 137254 : if(do_transpose) then
918 : call prep_index_wavef_bandpp(nproc_band,bandpp,&
919 13294 : & my_nspinor,ndatarecv,recvcounts,rdispls,index_wavef_band)
920 :
921 : ! -------------------------------------------------------
922 : ! Sorting of the waves functions below bandpp
923 : ! -------------------------------------------------------
924 13294 : if(hamk%gpu_option==ABI_GPU_OPENMP) then
925 : #ifdef HAVE_OPENMP_OFFLOAD
926 : !$OMP TARGET TEAMS DISTRIBUTE &
927 : !$OMP& PRIVATE(iibandpp) MAP(to:cwavef_alltoall1,cwavef_alltoall2,index_wavef_band)
928 : do iibandpp=1,bandpp*my_nspinor
929 : !$OMP PARALLEL DO PRIVATE(ind,ipw)
930 : do ipw = 1 ,ndatarecv
931 : ind=index_wavef_band(ipw + ndatarecv*(iibandpp-1))
932 : cwavef_alltoall2(1,ipw + ndatarecv*(iibandpp-1)) = cwavef_alltoall1(1,ind)
933 : cwavef_alltoall2(2,ipw + ndatarecv*(iibandpp-1)) = cwavef_alltoall1(2,ind)
934 : end do
935 : end do
936 : #endif
937 : else
938 126494086 : cwavef_alltoall2(:,:) = cwavef_alltoall1(:,index_wavef_band)
939 : end if
940 : end if
941 :
942 : ! -------------------------------------------------------
943 : ! Call nonlop
944 : ! -------------------------------------------------------
945 137254 : if(paw_opt == 2) then
946 46304 : lambda_nonlop(1:bandpp) = lambdablock((mpi_enreg%me_band*bandpp)+1:((mpi_enreg%me_band+1)*bandpp))
947 : end if
948 : call nonlop(choice,cpopt,cwaveprj,enlout,hamk,idir,lambda_nonlop,mpi_enreg,bandpp,nnlout,paw_opt,&
949 150548 : & signs,gsc_alltoall2,tim_nonlop,cwavef_alltoall2,gvnlc_alltoall2,vectproj=vectproj)
950 : #if defined(HAVE_GPU_CUDA) && defined(HAVE_YAKL)
951 : if(hamk%gpu_option==ABI_GPU_KOKKOS) call gpu_device_synchronize()
952 : !call gpu_data_prefetch_async_f(C_LOC(cwavef_alltoall2), cwavef_alltoall2_size, CPU_DEVICE_ID)
953 : !call gpu_data_prefetch_async_f(C_LOC(gvnlc_alltoall2), gvnlc_alltoall2_size, CPU_DEVICE_ID)
954 : !if (associated(gsc_alltoall2)) then
955 : ! call gpu_data_prefetch_async_f(C_LOC(gsc_alltoall2), gsc_alltoall2_size, CPU_DEVICE_ID)
956 : !end if
957 : #endif
958 :
959 : ! -----------------------------------------------------
960 : ! Sorting of waves functions below the processors
961 : ! -----------------------------------------------------
962 137254 : if(do_transpose.and.signs==2) then
963 0 : if (paw_opt/=3) gvnlc_alltoall1(:,index_wavef_band)=gvnlc_alltoall2(:,:)
964 0 : if (paw_opt==3.or.paw_opt==4) gsc_alltoall1(:,index_wavef_band)=gsc_alltoall2(:,:)
965 : end if
966 :
967 : end if
968 :
969 : !=====================================================================
970 : ! -------------------------------------------------------
971 : ! Deallocation
972 : ! -------------------------------------------------------
973 264842 : if (allocated(index_wavef_band)) then
974 20662 : ABI_FREE(index_wavef_band)
975 : end if
976 :
977 : !Transpose the gsc_alltoall or gvlnc_alltoall tabs
978 : !according to the paw_opt and signs values
979 264842 : if(do_transpose) then
980 139922 : if (signs==2) then
981 0 : call timab(581,1,tsec)
982 0 : if(bandpp/=1 .or. (bandpp==1 .and. mpi_enreg%paral_spinor==0.and.nspinortot==2))then
983 0 : if (paw_opt/=3) then
984 : call xmpi_alltoallv(gvnlc_alltoall1,recvcountsloc,rdisplsloc,gvnlc,&
985 0 : & sendcountsloc,sdisplsloc,spaceComm,ier)
986 : end if
987 0 : if (paw_opt==3.or.paw_opt==4) then
988 : call xmpi_alltoallv(gsc_alltoall1,recvcountsloc,rdisplsloc,gsc,&
989 0 : & sendcountsloc,sdisplsloc,spaceComm,ier)
990 : end if
991 : else
992 0 : if (paw_opt/=3) then
993 : call xmpi_alltoallv(gvnlc_alltoall2,recvcountsloc,rdisplsloc,gvnlc,&
994 0 : & sendcountsloc,sdisplsloc,spaceComm,ier)
995 : end if
996 0 : if (paw_opt==3.or.paw_opt==4) then
997 : call xmpi_alltoallv(gsc_alltoall2,recvcountsloc,rdisplsloc,gsc,&
998 0 : & sendcountsloc,sdisplsloc,spaceComm,ier)
999 : end if
1000 : end if
1001 0 : call timab(581,2,tsec)
1002 : end if
1003 : else
1004 : ! TODO check other usages, maybe
1005 124920 : if (l_gpu_option == ABI_GPU_KOKKOS) then
1006 : #if defined(HAVE_GPU_CUDA) && defined(HAVE_KOKKOS)
1007 : call copy_gpu_to_gpu(C_LOC(gsc), C_LOC(gsc_alltoall2), INT(2, c_size_t) * ndatarecv * my_nspinor * bandpp * dp)
1008 : #endif
1009 : else
1010 124920 : call DCOPY(2*ndatarecv*my_nspinor*bandpp, gsc_alltoall2, 1, gsc, 1)
1011 : end if
1012 : end if
1013 :
1014 264842 : if (nnlout>0) then
1015 107492 : call xmpi_allgather(enlout,nnlout*bandpp,enlout_block,spaceComm,ier)
1016 : end if
1017 264842 : ABI_FREE(enlout)
1018 264842 : ABI_FREE(sendcountsloc)
1019 264842 : ABI_FREE(sdisplsloc)
1020 264842 : ABI_FREE(recvcountsloc)
1021 264842 : ABI_FREE(rdisplsloc)
1022 :
1023 : #ifdef HAVE_OPENMP_OFFLOAD
1024 : if(present(cwavef_tr)) then
1025 : !$OMP TARGET UPDATE FROM(cwavef_alltoall2) IF(hamk%gpu_option==ABI_GPU_OPENMP)
1026 : end if
1027 : !$OMP TARGET EXIT DATA MAP(delete:cwavef_alltoall2) IF(hamk%gpu_option==ABI_GPU_OPENMP)
1028 : #endif
1029 :
1030 264842 : if(hamk%gpu_option==ABI_GPU_KOKKOS) then
1031 : #if defined HAVE_GPU && defined HAVE_YAKL
1032 : ABI_FREE_MANAGED(cwavef_alltoall2)
1033 : ABI_FREE_MANAGED(gvnlc_alltoall2)
1034 : if (paw_opt >= 3) then
1035 : ABI_FREE_MANAGED(gsc_alltoall2)
1036 : end if
1037 : #endif
1038 : else
1039 264842 : if(present(cwavef_tr)) then
1040 64 : nullify(cwavef_alltoall2)
1041 : else
1042 264778 : ABI_FREE(cwavef_alltoall2)
1043 : endif
1044 264842 : ABI_FREE(gvnlc_alltoall2)
1045 264842 : ABI_FREE(gsc_alltoall2)
1046 : end if
1047 :
1048 264842 : if(do_transpose .and. (bandpp/=1 .or. (bandpp==1 .and. mpi_enreg%paral_spinor==0.and.nspinortot==2)))then
1049 : #ifdef HAVE_OPENMP_OFFLOAD
1050 : !$OMP TARGET EXIT DATA MAP(delete:cwavef_alltoall1) IF(hamk%gpu_option==ABI_GPU_OPENMP)
1051 : #endif
1052 20662 : ABI_FREE(cwavef_alltoall1)
1053 20662 : if(signs==2)then
1054 0 : if (paw_opt/=3) then
1055 0 : ABI_FREE(gvnlc_alltoall1)
1056 : end if
1057 0 : if (paw_opt==3.or.paw_opt==4) then
1058 0 : ABI_FREE(gsc_alltoall1)
1059 : end if
1060 : end if
1061 : end if
1062 :
1063 264842 : call timab(570,2,tsec)
1064 :
1065 : DBG_EXIT('COLL')
1066 :
1067 529684 : end subroutine prep_nonlop
1068 : !!***
1069 :
1070 : !!****f* ABINIT/prep_fourwf
1071 : !! NAME
1072 : !! prep_fourwf
1073 : !!
1074 : !! FUNCTION
1075 : !! this routine prepares the data to the call of fourwf.
1076 : !!
1077 : !! INPUTS
1078 : !! blocksize= size of block for FFT
1079 : !! cwavef(2,npw*ndat)=planewave coefficients of wavefunction (one spinorial component?).
1080 : !! dtfil <type(datafiles_type)>=variables related to files
1081 : !! kg_k(3,npw_k)=reduced planewave coordinates.
1082 : !! lmnmax=if useylm=1, max number of (l,m,n) comp. over all type of psps
1083 : !! =if useylm=0, max number of (l,n) comp. over all type of psps
1084 : !! mgfft=maximum size of 1d ffts
1085 : !! mpi_enreg=information about mpi parallelization
1086 : !! mpsang= 1+maximum angular momentum for nonlocal pseudopotentials
1087 : !! mpssoang= 1+maximum (spin*angular momentum) for nonlocal pseudopotentials
1088 : !! natom=number of atoms in cell.
1089 : !! nband_k=number of bands at this k point for that spin polarization
1090 : !! ndat=number of FFT to do in //
1091 : !! ngfft(18)= contain all needed information about 3D FFT
1092 : !! npw_k=number of plane waves at this k point
1093 : !! nspinor=number of spinorial components of the wavefunctions
1094 : !! ntypat=number of types of atoms in unit cell.
1095 : !! n4,n5,n6 used for dimensionning of vlocal
1096 : !! option_fourwf=option for fourwf (see fourwf.F90)
1097 : !! prtvol=control print volume and debugging output
1098 : !! ucvol=unit cell volume
1099 : !! nfft_blocks=number of blocks fourwf is split into.
1100 : !! [bandfft_kpt_tab]= (optional) if present, contains tabs used to implement
1101 : !! the "band-fft" parallelism
1102 : !! if not present, the bandfft_kpt global variable is used
1103 : !! [gpu_option] = GPU implementation to use, i.e. cuda, openMP, ... (0=not using GPU)
1104 : !!
1105 : !! OUTPUT
1106 : !! gwavef=(2,npw*ndat)=matrix elements <G|H|C>.
1107 : !!
1108 : !! SIDE EFFECTS
1109 : !!
1110 : !! SOURCE
1111 :
1112 182182 : subroutine prep_fourwf(rhoaug,blocksize,cwavef,wfraug,iblock,istwf_k,mgfft,&
1113 182182 : & mpi_enreg,nband_k,ndat,ngfft,npw_k,n4,n5,n6,occ_k,option_fourwf,ucvol,wtk,&
1114 : & nfft_blocks,&
1115 : & bandfft_kpt_tab,gpu_option) ! Optional arguments
1116 :
1117 : !Arguments ------------------------------------
1118 : !scalars
1119 : integer,intent(in) :: blocksize,iblock,istwf_k,mgfft,n4,n5,n6,nband_k,ndat,npw_k,nfft_blocks
1120 : integer,intent(in) :: option_fourwf
1121 : integer,intent(in),optional :: gpu_option
1122 : real(dp),intent(in) :: ucvol,wtk
1123 : type(bandfft_kpt_type),optional,target,intent(in) :: bandfft_kpt_tab
1124 : type(mpi_type),intent(in) :: mpi_enreg
1125 : !arrays
1126 : integer,intent(in) :: ngfft(18)
1127 : real(dp),intent(in) :: occ_k(nband_k)
1128 : real(dp),intent(out) :: rhoaug(n4,n5,n6)
1129 : real(dp),intent(in), target :: cwavef(2,npw_k*blocksize)
1130 : real(dp),target,intent(inout) :: wfraug(:,:,:,:) !(2,n4,n5,n6*{ndat,ndat/nfft_blocks+mod(ndat,nfft_blocks))
1131 :
1132 : !Local variables-------------------------------
1133 : !scalars
1134 : integer :: bandpp,bandpp_sym,ier,iibandpp,ikpt_this_proc,ind_occ,ind_occ1,ind_occ2,ipw
1135 : integer :: istwf_k_,jjbandpp,me_fft,nd3,nproc_band,nproc_fft,npw_fft
1136 : integer :: nfft_blocks_sym,nband_fftblock
1137 : integer :: spaceComm=0,tim_fourwf,gpu_option_
1138 : integer,pointer :: idatarecv0,ndatarecv,ndatarecv_tot,ndatasend_sym
1139 : logical :: flag_inv_sym,have_to_reequilibrate,transfer_cwavef
1140 : real(dp) :: weight,weight1,weight2
1141 : type(bandfft_kpt_type),pointer :: bandfft_kpt_ptr
1142 : !arrays
1143 182182 : integer,contiguous, pointer :: indices_pw_fft(:),kg_k_fft(:,:),kg_k_gather(:,:),kg_k_gather_sym(:,:)
1144 182182 : integer,contiguous, pointer :: rdispls(:),rdispls_sym(:)
1145 182182 : integer,contiguous, pointer :: recvcounts(:),recvcount_fft(:),recvcounts_sym(:),recvcounts_sym_tot(:)
1146 182182 : integer,contiguous, pointer :: recvdisp_fft(:),sdispls(:),sdispls_sym(:)
1147 182182 : integer,contiguous, pointer :: sendcounts(:),sendcount_fft(:),sendcounts_sym(:),sendcounts_sym_all(:)
1148 182182 : integer,contiguous, pointer :: senddisp_fft(:),tab_proc(:)
1149 182182 : integer,allocatable :: rdisplsloc(:)
1150 182182 : integer,allocatable :: recvcountsloc(:),sdisplsloc(:)
1151 182182 : integer,allocatable :: sendcountsloc(:)
1152 182182 : integer,allocatable :: index_wavef_band(:),index_wavef_send(:)
1153 182182 : integer,pointer :: gbound_(:,:)
1154 : real(dp) :: dummy(2,1),tsec(2)
1155 182182 : real(dp),allocatable :: buff_wf(:,:)
1156 :
1157 : #if defined HAVE_GPU && defined HAVE_YAKL
1158 : real(c_double), contiguous, pointer :: cwavef_alltoall1(:,:) => null()
1159 : #else
1160 182182 : real(dp),allocatable :: cwavef_alltoall1(:,:)
1161 : #endif
1162 182182 : real(dp),allocatable :: cwavef_alltoall2(:,:)
1163 182182 : real(dp),allocatable :: cwavef_fft(:,:), cwavef_fft_tr(:,:)
1164 182182 : real(dp),allocatable :: weight_t(:),weight1_t(:),weight2_t(:)
1165 182182 : real(dp),pointer :: ewavef_alltoall_sym(:,:),ewavef_alltoall_sym_work(:,:),wfraug_ptr(:,:,:,:)
1166 :
1167 : #if defined HAVE_GPU && defined HAVE_YAKL
1168 : ! this buffer is necessary to avoid mixing "managed memory" buffer with "regular memory" buffer in MPI calls
1169 : ! Just to be clear:
1170 : ! - managed memory means memory allocated using ABI_MALLOC_MANAGED
1171 : ! - regular memory means memory allocated using either ABI_MALLOC or ABI_MALLOC_CUDA
1172 : !
1173 : ! here we chose to use a CPU buffer, would it be better to use a GPU buffer ? To be checked.
1174 : real(dp), allocatable :: cwavef_mpi(:,:)
1175 : !type(c_ptr) :: cwavef_mpi_c
1176 : !real(c_double),pointer :: cwavef_mpi(:,:)
1177 : #endif
1178 :
1179 : ! *************************************************************************
1180 :
1181 0 : ABI_CHECK((option_fourwf/=3),'Option=3 (FFT r->g) not implemented')
1182 182182 : ABI_CHECK((nfft_blocks>0),'nfft_blocks is null')
1183 182182 : ABI_CHECK((mpi_enreg%bandpp==ndat),'BUG: bandpp/=ndat')
1184 :
1185 182182 : spaceComm=mpi_enreg%comm_band
1186 182182 : nproc_band = mpi_enreg%nproc_band
1187 182182 : nproc_fft = mpi_enreg%nproc_fft
1188 182182 : bandpp = mpi_enreg%bandpp
1189 182182 : me_fft = mpi_enreg%me_fft
1190 :
1191 182182 : gpu_option_=ABI_GPU_DISABLED;if (present(gpu_option)) gpu_option_=gpu_option
1192 :
1193 182182 : if (present(bandfft_kpt_tab)) then
1194 : bandfft_kpt_ptr => bandfft_kpt_tab
1195 : else
1196 182182 : ikpt_this_proc=bandfft_kpt_get_ikpt()
1197 182182 : bandfft_kpt_ptr => bandfft_kpt(ikpt_this_proc)
1198 : end if
1199 :
1200 182182 : have_to_reequilibrate = bandfft_kpt_ptr%have_to_reequilibrate
1201 182182 : istwf_k_=istwf_k
1202 182182 : flag_inv_sym = (istwf_k_==2 .and. any(ngfft(7) == [401,402,312,512]))
1203 182182 : if (option_fourwf==0) flag_inv_sym=((flag_inv_sym).and.(gpu_option_==ABI_GPU_DISABLED))
1204 :
1205 182182 : if (flag_inv_sym) then
1206 6622 : istwf_k_ = 1
1207 6622 : if (modulo(bandpp,2)==0) then
1208 2494 : bandpp_sym = bandpp/2
1209 2494 : nfft_blocks_sym = nfft_blocks/2; if(modulo(nfft_blocks,2)/=0) nfft_blocks_sym=nfft_blocks_sym+1
1210 : else
1211 4128 : bandpp_sym = bandpp
1212 4128 : nfft_blocks_sym = nfft_blocks
1213 : end if
1214 : end if
1215 :
1216 182182 : if(have_to_reequilibrate .and. gpu_option_==ABI_GPU_OPENMP) then
1217 0 : ABI_BUG("Reequilibrating FFT isn't supported with OpenMP GPU yet !")
1218 : end if
1219 :
1220 : !====================================================================================
1221 546546 : ABI_MALLOC(sendcountsloc,(nproc_band))
1222 364364 : ABI_MALLOC(sdisplsloc ,(nproc_band))
1223 364364 : ABI_MALLOC(recvcountsloc,(nproc_band))
1224 364364 : ABI_MALLOC(rdisplsloc ,(nproc_band))
1225 :
1226 182182 : recvcounts =>bandfft_kpt_ptr%recvcounts(:)
1227 182182 : sendcounts =>bandfft_kpt_ptr%sendcounts(:)
1228 182182 : rdispls =>bandfft_kpt_ptr%rdispls (:)
1229 182182 : sdispls =>bandfft_kpt_ptr%sdispls (:)
1230 182182 : ndatarecv =>bandfft_kpt_ptr%ndatarecv
1231 :
1232 182182 : kg_k_gather =>bandfft_kpt_ptr%kg_k_gather(:,:)
1233 182182 : gbound_ =>bandfft_kpt_ptr%gbound(:,:)
1234 :
1235 182182 : if (flag_inv_sym ) then
1236 6622 : idatarecv0 =>bandfft_kpt_ptr%idatarecv0
1237 6622 : ndatarecv_tot =>bandfft_kpt_ptr%ndatarecv_tot
1238 6622 : ndatasend_sym =>bandfft_kpt_ptr%ndatasend_sym
1239 6622 : kg_k_gather_sym =>bandfft_kpt_ptr%kg_k_gather_sym(:,:)
1240 6622 : rdispls_sym =>bandfft_kpt_ptr%rdispls_sym(:)
1241 6622 : recvcounts_sym =>bandfft_kpt_ptr%recvcounts_sym(:)
1242 6622 : recvcounts_sym_tot =>bandfft_kpt_ptr%recvcounts_sym_tot(:)
1243 6622 : sdispls_sym =>bandfft_kpt_ptr%sdispls_sym(:)
1244 6622 : sendcounts_sym =>bandfft_kpt_ptr%sendcounts_sym(:)
1245 6622 : sendcounts_sym_all =>bandfft_kpt_ptr%sendcounts_sym_all(:)
1246 6622 : tab_proc =>bandfft_kpt_ptr%tab_proc(:)
1247 : end if
1248 :
1249 546546 : ABI_MALLOC(cwavef_alltoall2,(2,ndatarecv*bandpp))
1250 182182 : if ( ((.not.flag_inv_sym) .and. (bandpp>1) ) .or. flag_inv_sym )then
1251 37286 : if(gpu_option_==ABI_GPU_KOKKOS) then
1252 : #if defined HAVE_GPU && defined HAVE_YAKL
1253 : ABI_MALLOC_MANAGED(cwavef_alltoall1,(/2,ndatarecv*bandpp/))
1254 : #endif
1255 : else
1256 219468 : ABI_MALLOC(cwavef_alltoall1,(2,ndatarecv*bandpp))
1257 : end if
1258 : end if
1259 :
1260 599176 : recvcountsloc(:)=recvcounts(:)*2*bandpp
1261 599176 : rdisplsloc(:)=rdispls(:)*2*bandpp
1262 599176 : sendcountsloc(:)=sendcounts(:)*2
1263 599176 : sdisplsloc(:)=sdispls(:)*2
1264 :
1265 182182 : transfer_cwavef=.false.
1266 182182 : if(.not. xomp_target_is_present(c_loc(cwavef)) .and. gpu_option_==ABI_GPU_OPENMP) then
1267 182182 : transfer_cwavef=.true.
1268 : end if
1269 :
1270 : #ifdef HAVE_OPENMP_OFFLOAD
1271 : !$OMP TARGET ENTER DATA MAP(to:cwavef) IF(transfer_cwavef)
1272 : !$OMP TARGET ENTER DATA MAP(alloc:cwavef_alltoall2) IF(gpu_option_==ABI_GPU_OPENMP)
1273 : if ( ((.not.flag_inv_sym) .and. (bandpp>1) ) .or. flag_inv_sym )then
1274 : !$OMP TARGET ENTER DATA MAP(alloc:cwavef_alltoall1) IF(gpu_option_==ABI_GPU_OPENMP)
1275 : end if
1276 : #endif
1277 :
1278 182182 : call timab(547,1,tsec)
1279 182182 : if(gpu_option_==ABI_GPU_KOKKOS) then
1280 : #if defined HAVE_GPU && defined HAVE_YAKL
1281 : ABI_MALLOC(cwavef_mpi,(2,npw_k*blocksize))
1282 :
1283 : call gpu_data_prefetch_async(C_LOC(cwavef), INT(2, c_size_t)*npw_k*blocksize, CPU_DEVICE_ID)
1284 : call gpu_device_synchronize()
1285 :
1286 : cwavef_mpi(:,:) = cwavef(:,:)
1287 :
1288 : call xmpi_alltoallv(cwavef_mpi,sendcountsloc,sdisplsloc,cwavef_alltoall2,&
1289 : & recvcountsloc,rdisplsloc,spaceComm,ier)
1290 : ABI_FREE(cwavef_mpi)
1291 : #endif
1292 : else
1293 : call xmpi_alltoallv(cwavef,sendcountsloc,sdisplsloc,cwavef_alltoall2,&
1294 182182 : & recvcountsloc,rdisplsloc,spaceComm,ier,use_omp_map=(gpu_option_==ABI_GPU_OPENMP))
1295 : end if
1296 :
1297 : #ifdef HAVE_OPENMP_OFFLOAD
1298 : !$OMP TARGET EXIT DATA MAP(delete:cwavef) IF(transfer_cwavef)
1299 : #endif
1300 182182 : call timab(547,2,tsec)
1301 :
1302 182182 : tim_fourwf=16
1303 :
1304 : !Eventually adjust load balancing for FFT (by changing FFT distrib)
1305 182182 : if(have_to_reequilibrate) then
1306 0 : npw_fft = bandfft_kpt_ptr%npw_fft
1307 0 : sendcount_fft => bandfft_kpt_ptr%sendcount_fft(:)
1308 0 : recvcount_fft => bandfft_kpt_ptr%recvcount_fft(:)
1309 0 : senddisp_fft => bandfft_kpt_ptr%senddisp_fft(:)
1310 0 : recvdisp_fft => bandfft_kpt_ptr%recvdisp_fft(:)
1311 0 : indices_pw_fft => bandfft_kpt_ptr%indices_pw_fft(:)
1312 0 : kg_k_fft => bandfft_kpt_ptr%kg_k_fft(:,:)
1313 0 : ABI_MALLOC( buff_wf, (2,ndatarecv*bandpp) ) ! for sorting cgwavef
1314 0 : ABI_MALLOC( cwavef_fft, (2,npw_fft*bandpp) )
1315 0 : if(bandpp>1) then
1316 0 : ABI_MALLOC( cwavef_fft_tr, (2,npw_fft*bandpp))
1317 : end if
1318 : end if
1319 :
1320 182182 : if (option_fourwf==0) wfraug(:,:,:,:)=zero
1321 :
1322 : !====================================================================
1323 182182 : if ((.not.(flag_inv_sym)) .and. (bandpp==1)) then
1324 :
1325 : ! Compute the index of the band
1326 144896 : ind_occ = (iblock-1)*blocksize + mpi_enreg%me_band + 1
1327 :
1328 144896 : if(abs(occ_k(ind_occ))>=tol8.or.option_fourwf==0) then
1329 :
1330 : ! Compute the weight of the band
1331 73382 : weight=occ_k(ind_occ)*wtk/ucvol
1332 :
1333 73382 : if(have_to_reequilibrate) then
1334 : ! filling of sorted send buffers before exchange
1335 0 : do ipw = 1 ,ndatarecv
1336 0 : buff_wf(1:2, indices_pw_fft(ipw) ) = cwavef_alltoall2(1:2,ipw)
1337 : end do
1338 : call xmpi_alltoallv(buff_wf,2*sendcount_fft,2*senddisp_fft, &
1339 0 : & cwavef_fft,2*recvcount_fft, 2*recvdisp_fft, mpi_enreg%comm_fft,ier)
1340 : call fourwf(1,rhoaug,cwavef_fft,dummy,wfraug,gbound_,gbound_,&
1341 : & istwf_k_,kg_k_fft,kg_k_fft,mgfft,mpi_enreg,1,&
1342 : & ngfft,npw_fft,1,n4,n5,n6,option_fourwf,tim_fourwf,weight,weight,&
1343 0 : & gpu_option=gpu_option_)
1344 : else
1345 : call fourwf(1,rhoaug,cwavef_alltoall2,dummy,wfraug,gbound_,gbound_,&
1346 : & istwf_k_,kg_k_gather,kg_k_gather,mgfft,mpi_enreg,1,&
1347 : & ngfft,ndatarecv,1,n4,n5,n6,option_fourwf,tim_fourwf,weight,weight,&
1348 73382 : & gpu_option=gpu_option_)
1349 : end if
1350 73382 : if (option_fourwf==0.and.nproc_fft>1) then
1351 0 : if (me_fft>0) then
1352 0 : nd3=(ngfft(3)-1)/nproc_fft+1
1353 0 : wfraug(:,:,:,me_fft*nd3+1:me_fft*nd3+nd3)=wfraug(:,:,:,1:nd3)
1354 0 : wfraug(:,:,:,1:nd3)=zero
1355 : end if
1356 0 : call xmpi_sum(wfraug,mpi_enreg%comm_fft,ier)
1357 : end if
1358 : end if
1359 :
1360 : !====================================================================
1361 37286 : else if ((.not.(flag_inv_sym)) .and. (bandpp>1) ) then
1362 :
1363 : ! -------------------------------------------------------------
1364 : ! Computation of the index to class the waves functions below bandpp
1365 : ! -------------------------------------------------------------
1366 : call prep_index_wavef_bandpp(nproc_band,bandpp,&
1367 : & 1,ndatarecv,&
1368 : & recvcounts,rdispls,&
1369 30664 : & index_wavef_band)
1370 :
1371 : ! -------------------------------------------------------
1372 : ! Sorting of the wave functions below bandpp
1373 : ! -------------------------------------------------------
1374 30664 : if(gpu_option_==ABI_GPU_OPENMP) then
1375 : !FIXME Having this OpenMP kernel here cause a seg fault, so I put it in a separate routine
1376 : ! I can't figure what cause the issue...
1377 : call omp_copy_sort_wf(bandpp,ndatarecv,cwavef_alltoall1,cwavef_alltoall2,index_wavef_band,flag_inv_sym)
1378 : else
1379 98808688 : cwavef_alltoall1(:,:) = cwavef_alltoall2(:,index_wavef_band)
1380 : end if
1381 :
1382 30664 : if(have_to_reequilibrate) then
1383 : ! filling of sorted send buffers before exchange
1384 0 : do iibandpp=1,bandpp
1385 0 : do ipw = 1 ,ndatarecv
1386 : buff_wf(1:2, iibandpp + bandpp*(indices_pw_fft(ipw)-1)) = &
1387 0 : & cwavef_alltoall1(1:2,ipw + ndatarecv*(iibandpp-1))
1388 : end do
1389 : end do
1390 : call xmpi_alltoallv(buff_wf,2*bandpp*sendcount_fft,2*bandpp*senddisp_fft, &
1391 0 : & cwavef_fft_tr,2*bandpp*recvcount_fft, 2*bandpp*recvdisp_fft, mpi_enreg%comm_fft,ier)
1392 0 : do iibandpp=1,bandpp
1393 0 : do ipw = 1 ,npw_fft
1394 0 : cwavef_fft(1:2, ipw + npw_fft*(iibandpp -1)) = cwavef_fft_tr(1:2, iibandpp + bandpp*(ipw-1))
1395 : end do
1396 : end do
1397 : end if
1398 :
1399 : ! -------------------
1400 : ! Fourier calculation
1401 : ! -------------------
1402 : ! GPU version
1403 30664 : if(gpu_option_/=ABI_GPU_DISABLED) then
1404 0 : ABI_MALLOC(weight_t,(bandpp))
1405 0 : do iibandpp=1,bandpp
1406 : ! Compute the index of the band
1407 0 : ind_occ = (iblock-1)*blocksize + (mpi_enreg%me_band * bandpp) + iibandpp
1408 : ! Compute the weight of the band
1409 0 : weight_t(iibandpp)=occ_k(ind_occ)*wtk/ucvol
1410 0 : if(abs(occ_k(ind_occ)) < tol8) weight_t(iibandpp) = zero
1411 : end do
1412 :
1413 0 : nband_fftblock=bandpp/nfft_blocks+modulo(bandpp,nfft_blocks)
1414 : call fourwf_optmem(1,rhoaug,&
1415 : & cwavef_alltoall1,&
1416 : & dummy,wfraug(:,:,:,1:n6*nband_fftblock),gbound_,gbound_,&
1417 : & istwf_k_,kg_k_gather,kg_k_gather,mgfft,mpi_enreg,bandpp,nfft_blocks,&
1418 : & ngfft,ndatarecv,1,n4,n5,n6,option_fourwf,tim_fourwf,weight,weight,&
1419 : & weight_array_r=weight_t,weight_array_i=weight_t,&
1420 0 : & gpu_option=gpu_option_)
1421 0 : ABI_FREE(weight_t)
1422 :
1423 : ! Standard version
1424 : else
1425 145944 : do iibandpp=1,bandpp
1426 : ! Compute the index of the band
1427 115280 : ind_occ = (iblock-1)*blocksize + (mpi_enreg%me_band * bandpp) + iibandpp
1428 : ! Compute the weight of the band
1429 115280 : weight=occ_k(ind_occ)*wtk/ucvol
1430 115280 : if (option_fourwf==0) then
1431 0 : wfraug_ptr => wfraug(:,:,:,(iibandpp-1)*n6+1:iibandpp*n6)
1432 : else
1433 115280 : wfraug_ptr => wfraug
1434 : end if
1435 145944 : if (abs(occ_k(ind_occ)) >=tol8.or.option_fourwf==0) then
1436 55611 : if(have_to_reequilibrate) then
1437 : call fourwf(1,rhoaug, &
1438 : & cwavef_fft(:,(npw_fft*(iibandpp-1))+1:(npw_fft*iibandpp)), &
1439 : & dummy,wfraug_ptr,gbound_,gbound_,&
1440 : & istwf_k_,kg_k_fft,kg_k_fft,mgfft,mpi_enreg,1,&
1441 : & ngfft,npw_fft,1,n4,n5,n6,option_fourwf,tim_fourwf,weight,weight,&
1442 0 : & gpu_option=gpu_option_)
1443 : else
1444 : call fourwf(1,rhoaug,&
1445 : & cwavef_alltoall1(:,(ndatarecv*(iibandpp-1))+1:(ndatarecv*iibandpp)),&
1446 : & dummy,wfraug_ptr,gbound_,gbound_,&
1447 : & istwf_k_,kg_k_gather,kg_k_gather,mgfft,mpi_enreg,1,&
1448 : & ngfft,ndatarecv,1,n4,n5,n6,option_fourwf,&
1449 55611 : & tim_fourwf,weight,weight)
1450 : end if
1451 55611 : if (option_fourwf==0.and.nproc_fft>1) then
1452 0 : if (me_fft>0) then
1453 0 : nd3=(ngfft(3)-1)/nproc_fft+1
1454 0 : wfraug_ptr(:,:,:,me_fft*nd3+1:me_fft*nd3+nd3)=wfraug_ptr(:,:,:,1:nd3)
1455 0 : wfraug_ptr(:,:,:,1:nd3)=zero
1456 : end if
1457 0 : call xmpi_sum(wfraug_ptr,mpi_enreg%comm_fft,ier)
1458 : end if
1459 : end if
1460 : end do
1461 : end if ! (gpu_option/=0)
1462 :
1463 : ! -----------------------------------------------------
1464 : ! Sorting waves functions below the processors
1465 : ! -----------------------------------------------------
1466 : ! cwavef_alltoall(:,index_wavef_band) = cwavef_alltoall(:,:) ! NOT NEEDED
1467 30664 : ABI_FREE(index_wavef_band)
1468 :
1469 : !====================================================================
1470 6622 : else if (flag_inv_sym) then
1471 :
1472 : ! -------------------------------------------------------------
1473 : ! Computation of the index to class the waves functions below bandpp
1474 : ! -------------------------------------------------------------
1475 : call prep_index_wavef_bandpp(nproc_band,bandpp,&
1476 : & 1,ndatarecv,&
1477 : & recvcounts,rdispls,&
1478 6622 : & index_wavef_band)
1479 :
1480 : ! -------------------------------------------------------
1481 : ! Sorting the wave functions below bandpp
1482 : ! -------------------------------------------------------
1483 6622 : if(gpu_option_==ABI_GPU_OPENMP) then
1484 : !FIXME Having this OpenMP kernel here cause a seg fault, so I put it in a separate routine
1485 : ! I can't figure what cause the issue...
1486 : call omp_copy_sort_wf(bandpp,ndatarecv,cwavef_alltoall1,cwavef_alltoall2,index_wavef_band,flag_inv_sym)
1487 : else
1488 75855454 : cwavef_alltoall1(:,:) = cwavef_alltoall2(:,index_wavef_band)
1489 : end if
1490 :
1491 : ! ------------------------------------------------------------
1492 : ! We associate the waves functions by two
1493 : ! ------------------------------------------------------------
1494 : call prep_wavef_sym_do(mpi_enreg,bandpp,1,&
1495 : & ndatarecv,&
1496 : & ndatarecv_tot,ndatasend_sym,tab_proc,&
1497 : & cwavef_alltoall1,&
1498 : & sendcounts_sym,sdispls_sym,&
1499 : & recvcounts_sym,rdispls_sym,&
1500 : & ewavef_alltoall_sym,&
1501 6622 : & index_wavef_send)
1502 :
1503 : ! ------------------------------------------------------------
1504 : ! Fourier calculation
1505 : ! ------------------------------------------------------------
1506 : ! GPU version
1507 6622 : if (gpu_option_/=ABI_GPU_DISABLED) then
1508 0 : ABI_MALLOC(weight1_t,(bandpp_sym))
1509 0 : ABI_MALLOC(weight2_t,(bandpp_sym))
1510 0 : do iibandpp=1,bandpp_sym
1511 0 : if (bandpp/=1) then
1512 0 : ind_occ1 = (iblock-1)*blocksize + (mpi_enreg%me_band * bandpp) + (2*iibandpp-1)
1513 0 : ind_occ2 = (iblock-1)*blocksize + (mpi_enreg%me_band * bandpp) + (2*iibandpp )
1514 : else
1515 0 : ind_occ1 = (iblock-1)*blocksize + (mpi_enreg%me_band * bandpp) + 1
1516 0 : ind_occ2 = ind_occ1
1517 : end if
1518 0 : weight1_t(iibandpp) = occ_k(ind_occ1)*wtk/ucvol
1519 0 : weight2_t(iibandpp) = occ_k(ind_occ2)*wtk/ucvol
1520 : end do
1521 :
1522 0 : nband_fftblock=bandpp_sym/nfft_blocks_sym+modulo(bandpp_sym,nfft_blocks_sym)
1523 : call fourwf_optmem(1,rhoaug,&
1524 : & ewavef_alltoall_sym,&
1525 : & dummy,wfraug(:,:,:,1:n6*nband_fftblock),gbound_,gbound_,&
1526 : & istwf_k_,kg_k_gather_sym,kg_k_gather_sym,mgfft,mpi_enreg,bandpp_sym,nfft_blocks_sym,&
1527 : & ngfft,ndatarecv_tot,1,n4,n5,n6,option_fourwf,tim_fourwf,weight,weight,&
1528 : & weight_array_r=weight1_t,weight_array_i=weight2_t,&
1529 0 : & gpu_option=gpu_option_)
1530 :
1531 0 : ABI_FREE(weight1_t)
1532 0 : ABI_FREE(weight2_t)
1533 :
1534 : ! Standard version
1535 : else
1536 6622 : if (option_fourwf==0.and.bandpp>1) then
1537 0 : ABI_MALLOC(wfraug_ptr,(2,n4,n5,n6))
1538 : else
1539 6622 : wfraug_ptr => wfraug
1540 : end if
1541 23676 : do iibandpp=1,bandpp_sym
1542 17054 : if (bandpp/=1) then
1543 12926 : ind_occ1 = (iblock-1)*blocksize + (mpi_enreg%me_band * bandpp) + (2*iibandpp-1)
1544 12926 : ind_occ2 = (iblock-1)*blocksize + (mpi_enreg%me_band * bandpp) + (2*iibandpp )
1545 : else
1546 4128 : ind_occ1 = (iblock-1)*blocksize + (mpi_enreg%me_band * bandpp) + 1
1547 4128 : ind_occ2 = ind_occ1
1548 : end if
1549 17054 : weight1 = occ_k(ind_occ1)*wtk/ucvol
1550 17054 : weight2 = occ_k(ind_occ2)*wtk/ucvol
1551 17054 : ewavef_alltoall_sym_work => ewavef_alltoall_sym(:,(ndatarecv_tot*(iibandpp-1))+1:(ndatarecv_tot*iibandpp))
1552 : call fourwf(1,rhoaug,&
1553 : & ewavef_alltoall_sym_work,&
1554 : & dummy,wfraug_ptr,gbound_,gbound_,&
1555 : & istwf_k_,kg_k_gather_sym,kg_k_gather_sym,mgfft,mpi_enreg,1,&
1556 : & ngfft,ndatarecv_tot,1,n4,n5,n6,option_fourwf,&
1557 17054 : & tim_fourwf,weight1,weight2)
1558 23676 : if (option_fourwf==0) then
1559 0 : if (modulo(bandpp,2)==0) then
1560 0 : jjbandpp=2*iibandpp-1
1561 0 : wfraug(1,:,:,(jjbandpp-1)*n6+1:jjbandpp*n6)=wfraug_ptr(1,:,:,1:n6)
1562 0 : wfraug(1,:,:,(jjbandpp)*n6+1:(jjbandpp+1)*n6)=wfraug_ptr(2,:,:,1:n6)
1563 0 : else if (bandpp>1) then
1564 0 : wfraug(1,:,:,(iibandpp-1)*n6+1:iibandpp*n6)=wfraug_ptr(1,:,:,1:n6)
1565 : end if
1566 0 : if (nproc_fft>1) then
1567 0 : if (me_fft>0) then
1568 0 : nd3=(ngfft(3)-1)/nproc_fft+1
1569 0 : wfraug(1,:,:,me_fft*nd3+1:me_fft*nd3+nd3)=wfraug(1,:,:,1:nd3)
1570 0 : wfraug(1,:,:,1:nd3)=zero
1571 : end if
1572 0 : call xmpi_sum(wfraug,mpi_enreg%comm_fft,ier)
1573 : end if
1574 : end if
1575 : end do
1576 6622 : if (option_fourwf==0.and.bandpp>1) then
1577 0 : ABI_FREE(wfraug_ptr)
1578 : end if
1579 : end if ! (gpu_option/=ABI_GPU_DISABLED)
1580 :
1581 : ! ------------------------------------------------------------
1582 : ! We dissociate each wave function in two waves functions
1583 : ! gwavef is classed below of bandpp
1584 : ! ------------------------------------------------------------
1585 : call prep_wavef_sym_undo(mpi_enreg,bandpp,1,&
1586 : & ndatarecv,&
1587 : & ndatarecv_tot,ndatasend_sym,idatarecv0,&
1588 : & cwavef_alltoall1,&
1589 : & sendcounts_sym,sdispls_sym,&
1590 : & recvcounts_sym,rdispls_sym,&
1591 : & ewavef_alltoall_sym,&
1592 6622 : & index_wavef_send)
1593 :
1594 6622 : ABI_FREE(ewavef_alltoall_sym)
1595 6622 : ABI_FREE(index_wavef_send)
1596 :
1597 : ! -------------------------------------------------------
1598 : ! Sorting waves functions below the processors
1599 : ! -------------------------------------------------------
1600 : ! cwavef_alltoall(:,index_wavef_band) = cwavef_alltoall(:,:) ! NOT NEEDED
1601 :
1602 6622 : ABI_FREE(index_wavef_band)
1603 :
1604 : end if
1605 :
1606 : !====================================================================
1607 182182 : if(have_to_reequilibrate) then
1608 0 : ABI_FREE(buff_wf)
1609 0 : ABI_FREE(cwavef_fft)
1610 0 : if(bandpp > 1) then
1611 0 : ABI_FREE(cwavef_fft_tr)
1612 : end if
1613 : end if
1614 : #ifdef HAVE_OPENMP_OFFLOAD
1615 : !$OMP TARGET EXIT DATA MAP(delete:cwavef_alltoall2) IF(gpu_option_==ABI_GPU_OPENMP)
1616 : if ( ((.not.flag_inv_sym) .and. (bandpp>1) ) .or. flag_inv_sym ) then
1617 : !$OMP TARGET EXIT DATA MAP(delete:cwavef_alltoall1) IF(gpu_option_==ABI_GPU_OPENMP)
1618 : end if
1619 : #endif
1620 182182 : ABI_FREE(sendcountsloc)
1621 182182 : ABI_FREE(sdisplsloc)
1622 182182 : ABI_FREE(recvcountsloc)
1623 182182 : ABI_FREE(rdisplsloc)
1624 182182 : ABI_FREE(cwavef_alltoall2)
1625 401650 : if ( ((.not.flag_inv_sym) .and. (bandpp>1) ) .or. flag_inv_sym ) then
1626 37286 : if(gpu_option_==ABI_GPU_KOKKOS) then
1627 : #if defined HAVE_GPU && defined HAVE_YAKL
1628 : ABI_FREE_MANAGED(cwavef_alltoall1)
1629 : #endif
1630 : else
1631 37286 : ABI_FREE(cwavef_alltoall1)
1632 : end if
1633 : end if
1634 :
1635 : contains
1636 37286 : subroutine omp_copy_sort_wf(bandpp,ndatarecv,cwavef_alltoall_out,cwavef_alltoall_in,index_wavef_band,flag_inv_sym)
1637 : !Arguments ------------------------------------
1638 : !scalars
1639 : integer,intent(in) :: bandpp,ndatarecv
1640 : logical,intent(in) :: flag_inv_sym
1641 : !arrays
1642 : integer,intent(in) :: index_wavef_band(bandpp*ndatarecv)
1643 : real(dp),intent(in) :: cwavef_alltoall_in(2,bandpp*ndatarecv)
1644 : real(dp),intent(out) :: cwavef_alltoall_out(2,bandpp*ndatarecv)
1645 :
1646 : !Locals ---------------------------------------
1647 : integer :: ind,iibandpp,ipw
1648 :
1649 : ! *************************************************************************
1650 :
1651 : #ifdef HAVE_OPENMP_OFFLOAD
1652 : !FIXME This doesn't run fine when flag_invsym is on, why !!???
1653 : !$OMP TARGET UPDATE FROM(cwavef_alltoall_in) IF(flag_inv_sym)
1654 :
1655 : !$OMP TARGET TEAMS DISTRIBUTE &
1656 : !$OMP& PRIVATE(iibandpp) MAP(to:cwavef_alltoall_out,cwavef_alltoall_in,index_wavef_band) &
1657 : !$OMP& IF(.not. flag_inv_sym)
1658 : do iibandpp=1,bandpp
1659 : !$OMP PARALLEL DO PRIVATE(ind,ipw)
1660 : do ipw = 1 ,ndatarecv
1661 : ind=index_wavef_band(ipw + ndatarecv*(iibandpp-1))
1662 : cwavef_alltoall_out(1,ipw + ndatarecv*(iibandpp-1)) = cwavef_alltoall_in(1,ind)
1663 : cwavef_alltoall_out(2,ipw + ndatarecv*(iibandpp-1)) = cwavef_alltoall_in(2,ind)
1664 : end do
1665 : end do
1666 :
1667 : !$OMP TARGET UPDATE TO(cwavef_alltoall_out) IF(flag_inv_sym)
1668 :
1669 : #else
1670 : ABI_UNUSED((/ind,iibandpp,ipw/))
1671 : ABI_UNUSED((/bandpp,ndatarecv/))
1672 : ABI_UNUSED(flag_inv_sym)
1673 : ABI_UNUSED(cwavef_alltoall_in)
1674 : ABI_UNUSED(cwavef_alltoall_out)
1675 : ABI_UNUSED(index_wavef_band)
1676 : #endif
1677 : end subroutine omp_copy_sort_wf
1678 :
1679 : end subroutine prep_fourwf
1680 : !!***
1681 :
1682 : !!****f* ABINIT/prep_wavef_sym_do
1683 : !! NAME
1684 : !! prep_wavef_sym_do
1685 : !!
1686 : !! FUNCTION
1687 : !! this routine associates waves functions by two as following
1688 : !! E(G) = C(G) + D(G)
1689 : !! E(-G) = C*(G) + iD*(G)
1690 : !! the values are distributed on the processors in function of
1691 : !! the value of mpi_enreg%distribfft%tab_fftwf2_distrib( (-kg_k_gather(2,i) )
1692 : !!
1693 : !! INPUTS
1694 : !! mpi_enreg = information about mpi parallelization
1695 : !! bandpp = number of couple of waves functions
1696 : !! nspinor = number of spin
1697 : !! ndatarecv = number of values received by the processor and sended
1698 : !! by the other processors band
1699 : !! ndatarecv_tot = total number of received values
1700 : !! (ndatarecv + number of received opposited planewave coordinates)
1701 : !! ndatasend_sym = number of sended values to the processors fft to create opposited
1702 : !! planewave coordinates
1703 : !! tab_proc = positions of opposited planewave coordinates in the list of the
1704 : !! processors fft
1705 : !! cwavef_alltoall = planewave coefficients of wavefunction
1706 : !! ( initial of the processor + sended by other processors band)
1707 : !! sendcounts_sym = number of sended values by the processor to each processor fft
1708 : !! sdispls_sym = postions of the sended values by the processor to each processor fft
1709 : !!
1710 : !! recvcounts_sym = number of the received values by the processor from each processor fft
1711 : !! rdispls_sym = postions of the received values by the processor from each processor fft
1712 : !!
1713 : !! OUTPUT
1714 : !! ewavef_alltoall_sym = planewave coefficients of wavefunction
1715 : !! initial of the processor +
1716 : !! sended by other processors band +
1717 : !! sended by other processors fft +
1718 : !! and compisited if bandpp >1
1719 : !! index_wavef_send = index to send the values in blocks to the other processor fft
1720 : !!
1721 : !! SIDE EFFECTS
1722 : !!
1723 : !! SOURCE
1724 :
1725 9896 : subroutine prep_wavef_sym_do(mpi_enreg,bandpp,nspinor,&
1726 : & ndatarecv,&
1727 19792 : & ndatarecv_tot,ndatasend_sym,tab_proc,&
1728 9896 : & cwavef_alltoall,&
1729 9896 : & sendcounts_sym,sdispls_sym,&
1730 9896 : & recvcounts_sym,rdispls_sym,&
1731 : & ewavef_alltoall_sym,&
1732 : & index_wavef_send)
1733 :
1734 : !Arguments ------------------------------------
1735 : !scalars
1736 : integer,intent(in) :: bandpp,ndatarecv,ndatarecv_tot,ndatasend_sym
1737 : integer,intent(in) :: nspinor
1738 : type(mpi_type),intent(in) :: mpi_enreg
1739 : !arrays
1740 : integer,allocatable,intent(out) :: index_wavef_send(:)
1741 : integer,intent(in) :: rdispls_sym(:),recvcounts_sym(:)
1742 : integer,intent(in) :: sdispls_sym(:),sendcounts_sym(:)
1743 : integer,intent(in) :: tab_proc(:)
1744 : real(dp),intent(inout) :: cwavef_alltoall(2,ndatarecv*nspinor*bandpp)
1745 : real(dp),pointer :: ewavef_alltoall_sym(:,:)
1746 :
1747 : !Local variables-------------------------------
1748 : !scalars
1749 : integer :: bandpp_sym,ibandpp,idatarecv,ideb_loc,idebc,idebd,idebe
1750 : integer :: ier,ifin_loc,ifinc,ifind,ifine,iproc,jbandpp,jsendloc
1751 : integer :: kbandpp,newspacecomm,nproc_fft
1752 : logical :: flag_compose
1753 : !arrays
1754 : integer,allocatable :: rdispls_sym_loc(:),recvcounts_sym_loc(:)
1755 : integer,allocatable :: sdispls_sym_loc(:),sendcounts_sym_loc(:)
1756 9896 : real(dp),allocatable :: ewavef_alltoall_loc(:,:),ewavef_alltoall_send(:,:)
1757 :
1758 : ! *********************************************************************
1759 :
1760 : !DEBUG
1761 : !write(std_out,*)' prep_wavef_sym_do : enter '
1762 : !ENDDEBUG
1763 :
1764 : !---------------------------------------------
1765 : !Initialisation
1766 : !---------------------------------------------
1767 9896 : nproc_fft = mpi_enreg%nproc_fft
1768 :
1769 9896 : newspacecomm = mpi_enreg%comm_fft
1770 :
1771 9896 : if (modulo(bandpp,2)==0) then
1772 4808 : bandpp_sym = bandpp/2
1773 4808 : flag_compose = .TRUE.
1774 : else
1775 : bandpp_sym = bandpp
1776 : flag_compose = .FALSE.
1777 : end if
1778 :
1779 : !---------------------------------------------
1780 : !Allocation
1781 : !---------------------------------------------
1782 29688 : ABI_MALLOC(ewavef_alltoall_sym ,(2,ndatarecv_tot*bandpp_sym))
1783 29688 : ABI_MALLOC(ewavef_alltoall_loc ,(2,ndatarecv *bandpp_sym))
1784 29688 : ABI_MALLOC(ewavef_alltoall_send ,(2,ndatasend_sym*bandpp_sym))
1785 29688 : ABI_MALLOC(index_wavef_send ,( ndatasend_sym*bandpp_sym))
1786 :
1787 29688 : ABI_MALLOC(sendcounts_sym_loc ,(nproc_fft))
1788 19792 : ABI_MALLOC(sdispls_sym_loc ,(nproc_fft))
1789 19792 : ABI_MALLOC(recvcounts_sym_loc ,(nproc_fft))
1790 19792 : ABI_MALLOC(rdispls_sym_loc ,(nproc_fft))
1791 :
1792 :
1793 : !Initialisation
1794 : !--------------
1795 106566374 : ewavef_alltoall_sym(:,:) =0.
1796 53319068 : ewavef_alltoall_loc(:,:) =0.
1797 :
1798 21958 : sendcounts_sym_loc(:) =0
1799 21958 : sdispls_sym_loc(:) =0
1800 21958 : recvcounts_sym_loc(:) =0
1801 21958 : rdispls_sym_loc(:) =0
1802 :
1803 17758998 : index_wavef_send(:) =0
1804 :
1805 :
1806 : !-------------------------------------------------
1807 : !We are bandpp blocks which we want to :
1808 : !associate by two (band_sym==bandpp/2)
1809 : !or not associate by two (band_sym==bandpp)
1810 : !
1811 : !So We'll have got bandpp_sym blocks
1812 : !So we loop on the bandpp_sym blocks
1813 : !--------------------------------------------------
1814 :
1815 32494 : do kbandpp=1,bandpp_sym
1816 :
1817 : ! position of the two blocks
1818 : ! --------------------------
1819 22598 : ibandpp = (kbandpp-1) * 2
1820 22598 : jbandpp = ibandpp + 1
1821 :
1822 22598 : idebe = (kbandpp-1) * ndatarecv_tot + 1
1823 22598 : ifine = idebe + ndatarecv - 1
1824 :
1825 22598 : idebc = ibandpp * ndatarecv + 1
1826 22598 : ifinc = idebc + ndatarecv - 1
1827 :
1828 22598 : idebd = jbandpp * ndatarecv + 1
1829 22598 : ifind = idebd + ndatarecv - 1
1830 :
1831 22598 : ideb_loc = (kbandpp-1) * ndatarecv + 1
1832 22598 : ifin_loc = ideb_loc + ndatarecv - 1
1833 :
1834 :
1835 32494 : if (flag_compose) then
1836 :
1837 :
1838 : ! calcul ewavef(G)
1839 : ! ----------------
1840 : ewavef_alltoall_sym(1,idebe:ifine) = &
1841 : & cwavef_alltoall(1,idebc:ifinc) &
1842 16760514 : & - cwavef_alltoall(2,idebd:ifind)
1843 :
1844 : ewavef_alltoall_sym(2,idebe:ifine) = &
1845 : & cwavef_alltoall(2,idebc:ifinc) &
1846 16760514 : & + cwavef_alltoall(1,idebd:ifind)
1847 :
1848 : ! calcul ewavef_loc(-G)
1849 : ! ---------------------
1850 : ewavef_alltoall_loc(1,ideb_loc:ifin_loc) = &
1851 : & cwavef_alltoall(1,idebc:ifinc) &
1852 16760514 : & + cwavef_alltoall(2,idebd:ifind)
1853 :
1854 : ewavef_alltoall_loc(2,ideb_loc:ifin_loc) = &
1855 : & - cwavef_alltoall(2,idebc:ifinc) &
1856 16760514 : & + cwavef_alltoall(1,idebd:ifind)
1857 : else
1858 :
1859 : ! calcul ewavef(G)
1860 : ! ----------------
1861 1031808 : ewavef_alltoall_sym(1,idebe:ifine) = cwavef_alltoall(1,idebc:ifinc)
1862 1031808 : ewavef_alltoall_sym(2,idebe:ifine) = cwavef_alltoall(2,idebc:ifinc)
1863 :
1864 : ! calcul ewavef_loc(-G)
1865 : ! ---------------------
1866 1031808 : ewavef_alltoall_loc(1,ideb_loc:ifin_loc) = cwavef_alltoall(1,idebc:ifinc)
1867 1031808 : ewavef_alltoall_loc(2,ideb_loc:ifin_loc) = - cwavef_alltoall(2,idebc:ifinc)
1868 :
1869 : end if
1870 :
1871 : end do
1872 :
1873 :
1874 :
1875 : !------------------------------------------------------------------------
1876 : !Creation of datas blocks for each processor fft from ewavef_alltoall_loc
1877 : !to send datas by blocks with a alltoall...
1878 : !------------------------------------------------------------------------
1879 :
1880 : !Position of the blocks
1881 : !----------------------
1882 : jsendloc=0
1883 32494 : do ibandpp=1,bandpp_sym
1884 59044 : do iproc=1,nproc_fft
1885 20112644 : do idatarecv=1,ndatarecv
1886 20090046 : if (tab_proc(idatarecv)==(iproc-1)) then
1887 17749102 : jsendloc=jsendloc+1
1888 17749102 : index_wavef_send(jsendloc) = idatarecv + ndatarecv * (ibandpp-1)
1889 : end if
1890 : end do
1891 : end do
1892 : end do
1893 :
1894 : !Classment
1895 : !----------
1896 53257202 : ewavef_alltoall_send(:,:)=ewavef_alltoall_loc(:,index_wavef_send)
1897 :
1898 :
1899 : !-------------------------------------------------
1900 : !Calcul of the number of received and sended datas
1901 : !-------------------------------------------------
1902 31854 : sendcounts_sym_loc = sendcounts_sym*2
1903 31854 : recvcounts_sym_loc = recvcounts_sym*2
1904 :
1905 : !------------------------------------------
1906 : !Exchange of the datas ewavef_allto_all_loc
1907 : !------------------------------------------
1908 32494 : do ibandpp=1,bandpp_sym
1909 :
1910 : ! ------------------------------------------------
1911 : ! Deplacment of the sended datas because of bandpp
1912 : ! ------------------------------------------------
1913 49148 : sdispls_sym_loc(:) = sdispls_sym(:) + ndatasend_sym * (ibandpp-1)
1914 49148 : sdispls_sym_loc = sdispls_sym_loc *2
1915 :
1916 : ! --------------------------------------------------
1917 : ! Deplacment of the received datas because of bandpp
1918 : ! --------------------------------------------------
1919 49148 : rdispls_sym_loc(:) = rdispls_sym(:) + ndatarecv_tot * (ibandpp-1)
1920 49148 : rdispls_sym_loc = rdispls_sym_loc *2
1921 :
1922 :
1923 : call xmpi_alltoallv(&
1924 : & ewavef_alltoall_send(:,:) ,sendcounts_sym_loc,sdispls_sym_loc,&
1925 : & ewavef_alltoall_sym(:,:) ,recvcounts_sym_loc,rdispls_sym_loc,&
1926 32494 : & newspacecomm,ier)
1927 :
1928 : end do
1929 :
1930 : !-----------------------
1931 : !Desallocation
1932 : !-----------------------
1933 :
1934 9896 : ABI_FREE(sendcounts_sym_loc)
1935 9896 : ABI_FREE(recvcounts_sym_loc)
1936 9896 : ABI_FREE(sdispls_sym_loc)
1937 9896 : ABI_FREE(rdispls_sym_loc)
1938 :
1939 9896 : ABI_FREE(ewavef_alltoall_loc)
1940 9896 : ABI_FREE(ewavef_alltoall_send)
1941 :
1942 9896 : end subroutine prep_wavef_sym_do
1943 : !!***
1944 :
1945 : !!****f* ABINIT/prep_wavef_sym_undo
1946 : !! NAME
1947 : !! prep_wavef_sym_undo
1948 : !!
1949 : !! FUNCTION
1950 : !! this routine dissociates each wave function in two waves functions as following
1951 : !! C(G) = ( E*(-G) + E(G))/2
1952 : !! D(G) = i*( E*(-G) - E(G))/2
1953 : !! the values are redistributed on the processors in function of
1954 : !! the value of mpi_enreg%distribfft%tab_fftwf2_distrib( (-kg_k_gather(2,i) )
1955 : !!
1956 : !! INPUTS
1957 : !! mpi_enreg = information about mpi parallelization
1958 : !! bandpp = number of groups of couple of waves functions
1959 : !! nspinor = number of spin
1960 : !! ndatarecv = number of values received by the processor and sended
1961 : !! by the other processors band
1962 : !! ndatarecv_tot = total number of received values
1963 : !! (ndatarecv + number of received opposited planewave coordinates)
1964 : !! ndatasend_sym = number of sended values to the processors fft to create opposited
1965 : !! planewave coordinates
1966 : !! idatarecv0 = position of the planewave coordinates (0,0,0)
1967 : !! sendcounts_sym = number of sended values by the processor to each processor fft
1968 : !! sdispls_sym = postions of the sended values by the processor to each processor fft
1969 : !!
1970 : !! recvcounts_sym = number of the received values by the processor to each processor fft
1971 : !!! rdispls_sym = postions of the received values by the processor to each processor fft
1972 : !!
1973 : !! gwavef_alltoall_sym = planewave coefficients of wavefunction
1974 : !! initial of the processor +
1975 : !! sended by other processors band +
1976 : !! sended by other processors fft +
1977 : !! and composited if bandpp >1
1978 : !! index_wavef_send = index to send the values by block to the other processor fft
1979 : !!
1980 : !! OUTPUT
1981 : !! gwavef_alltoall = planewave coefficients of wavefunction
1982 : !! ( for of the processor + to send to other processors band)
1983 : !!
1984 : !! SOURCE
1985 :
1986 12576 : subroutine prep_wavef_sym_undo(mpi_enreg,bandpp,nspinor,&
1987 : & ndatarecv,&
1988 : & ndatarecv_tot,ndatasend_sym,idatarecv0,&
1989 12576 : & gwavef_alltoall,&
1990 12576 : & sendcounts_sym,sdispls_sym,&
1991 12576 : & recvcounts_sym,rdispls_sym,&
1992 12576 : & gwavef_alltoall_sym,&
1993 12576 : & index_wavef_send)
1994 :
1995 : !Arguments ------------------------------------
1996 : !scalars
1997 : integer,intent(in) :: bandpp,idatarecv0,ndatarecv,ndatarecv_tot,ndatasend_sym
1998 : integer,intent(in) :: nspinor
1999 : type(mpi_type),intent(in) :: mpi_enreg
2000 : !arrays
2001 : integer,intent(in) :: index_wavef_send(:),rdispls_sym(:),recvcounts_sym(:)
2002 : integer,intent(in) :: sdispls_sym(:),sendcounts_sym(:)
2003 : real(dp),intent(inout) :: gwavef_alltoall(2,ndatarecv*nspinor*bandpp)
2004 : real(dp),intent(inout) :: gwavef_alltoall_sym(:,:)
2005 :
2006 : !Local variables-------------------------------
2007 : !scalars
2008 : integer :: bandpp_sym,ibandpp,ideb_loc,idebc,idebd
2009 : integer :: idebe,ier,ifin_loc,ifinc,ifind,ifine
2010 : integer :: jbandpp,kbandpp,newspacecomm,nproc_fft
2011 : logical :: flag_compose
2012 : !arrays
2013 : integer,allocatable :: rdispls_sym_loc(:),recvcounts_sym_loc(:)
2014 : integer,allocatable :: sdispls_sym_loc(:),sendcounts_sym_loc(:)
2015 12576 : real(dp),allocatable :: gwavef_alltoall_loc(:,:),gwavef_alltoall_rcv(:,:)
2016 :
2017 : ! *********************************************************************
2018 :
2019 : !DEBUG
2020 : !write(std_out,*)' prep_wavef_sym_undo : enter '
2021 : !ENDDEBUG
2022 :
2023 :
2024 : !---------------------------------------------
2025 : !Initialisation
2026 : !---------------------------------------------
2027 12576 : nproc_fft = mpi_enreg%nproc_fft
2028 :
2029 12576 : newspacecomm = mpi_enreg%comm_fft
2030 :
2031 12576 : if (modulo(bandpp,2)==0) then
2032 7488 : bandpp_sym = bandpp/2
2033 7488 : flag_compose = .TRUE.
2034 : else
2035 : bandpp_sym = bandpp
2036 : flag_compose = .FALSE.
2037 : end if
2038 :
2039 : !---------------------------------------------
2040 : !Allocation
2041 : !---------------------------------------------
2042 37728 : ABI_MALLOC(gwavef_alltoall_loc ,(2,ndatarecv *bandpp_sym))
2043 37728 : ABI_MALLOC(gwavef_alltoall_rcv ,(2,ndatasend_sym *bandpp_sym))
2044 :
2045 37728 : ABI_MALLOC(sendcounts_sym_loc ,(nproc_fft))
2046 25152 : ABI_MALLOC(sdispls_sym_loc ,(nproc_fft))
2047 25152 : ABI_MALLOC(recvcounts_sym_loc ,(nproc_fft))
2048 25152 : ABI_MALLOC(rdispls_sym_loc ,(nproc_fft))
2049 :
2050 :
2051 : !---------------------------------------------
2052 : !Initialisation
2053 : !---------------------------------------------
2054 67046016 : gwavef_alltoall_loc(:,:) =0.
2055 :
2056 27966 : sendcounts_sym_loc(:) =0
2057 27966 : sdispls_sym_loc(:) =0
2058 27966 : recvcounts_sym_loc(:) =0
2059 27966 : rdispls_sym_loc(:) =0
2060 :
2061 :
2062 : !-------------------------------------------------
2063 : !Calcul of number of the sended and received datas
2064 : !-------------------------------------------------
2065 40542 : sendcounts_sym_loc = sendcounts_sym*2
2066 40542 : recvcounts_sym_loc = recvcounts_sym*2
2067 :
2068 : !----------------------------------------------------
2069 : !Sending of the values
2070 : !----------------------------------------------------
2071 39930 : do ibandpp = 1,bandpp_sym
2072 :
2073 : ! -------------------------------------------------
2074 : ! Deplacment of the sended values because of bandpp
2075 : ! -------------------------------------------------
2076 60632 : sdispls_sym_loc(:) = sdispls_sym(:) + ndatasend_sym * (ibandpp-1)
2077 60632 : sdispls_sym_loc = sdispls_sym_loc *2
2078 :
2079 : ! ---------------------------------------------------
2080 : ! Deplacment of the received values because of bandpp
2081 : ! ---------------------------------------------------
2082 60632 : rdispls_sym_loc(:) = rdispls_sym(:) + ndatarecv_tot * (ibandpp-1)
2083 60632 : rdispls_sym_loc = rdispls_sym_loc *2
2084 :
2085 :
2086 : call xmpi_alltoallv(&
2087 : & gwavef_alltoall_sym(:,:) ,recvcounts_sym_loc,rdispls_sym_loc,&
2088 : & gwavef_alltoall_rcv(:,:) ,sendcounts_sym_loc,sdispls_sym_loc,&
2089 39930 : & newspacecomm,ier)
2090 :
2091 : end do
2092 :
2093 :
2094 : !----------------------
2095 : !Dispatching the blocks
2096 : !----------------------
2097 66972840 : gwavef_alltoall_loc(:,index_wavef_send(:)) = gwavef_alltoall_rcv(:,:)
2098 :
2099 : !----------------------
2100 : !Case -kg = [0 0 0]
2101 : !----------------------
2102 12576 : if (idatarecv0/=-1) then
2103 35561 : do kbandpp=1,bandpp_sym
2104 : gwavef_alltoall_loc(:,(kbandpp-1)*ndatarecv + idatarecv0)= &
2105 84345 : gwavef_alltoall_sym(:,(kbandpp-1)*ndatarecv_tot + idatarecv0)
2106 : end do
2107 : end if
2108 :
2109 : !---------------------------------------------------
2110 : !Build of hwavef_alltoall
2111 : !
2112 : !We have got :
2113 : !bandpp_sym blocks to dissociate
2114 : !or bandpp_sym blokcs to not dissociate
2115 : !--------------------------------------------------
2116 39930 : do kbandpp=1,bandpp_sym
2117 :
2118 : ! position of the 2 blocks
2119 : ! ----------------------------------
2120 27354 : ibandpp = (kbandpp-1) * 2
2121 27354 : jbandpp = ibandpp + 1
2122 :
2123 27354 : idebe = (kbandpp-1) * ndatarecv_tot + 1
2124 27354 : ifine = idebe + ndatarecv - 1
2125 :
2126 27354 : idebc = ibandpp * ndatarecv + 1
2127 27354 : ifinc = idebc + ndatarecv - 1
2128 :
2129 27354 : idebd = jbandpp * ndatarecv + 1
2130 27354 : ifind = idebd + ndatarecv - 1
2131 :
2132 27354 : ideb_loc = (kbandpp-1) * ndatarecv + 1
2133 27354 : ifin_loc = ideb_loc + ndatarecv - 1
2134 :
2135 :
2136 39930 : if (flag_compose) then
2137 :
2138 : ! calcul cwavef(G)
2139 : ! ----------------
2140 : gwavef_alltoall(1,idebc:ifinc) = gwavef_alltoall_sym(1,idebe:ifine) &
2141 21340026 : & + gwavef_alltoall_loc(1,ideb_loc:ifin_loc)
2142 : gwavef_alltoall(2,idebc:ifinc) = gwavef_alltoall_sym(2,idebe:ifine) &
2143 21340026 : & - gwavef_alltoall_loc(2,ideb_loc:ifin_loc)
2144 :
2145 : ! calcul dwavef(G)
2146 : ! ------------------
2147 : gwavef_alltoall(1,idebd:ifind) = gwavef_alltoall_sym(2,idebe:ifine) &
2148 21340026 : & + gwavef_alltoall_loc(2,ideb_loc:ifin_loc)
2149 : gwavef_alltoall(2,idebd:ifind) = - gwavef_alltoall_sym(1,idebe:ifine) &
2150 21340026 : & + gwavef_alltoall_loc(1,ideb_loc:ifin_loc)
2151 : else
2152 :
2153 : ! calcul cwavef(G)
2154 : ! ----------------
2155 : gwavef_alltoall(1,idebc:ifinc) = gwavef_alltoall_sym(1,idebe:ifine) &
2156 1031808 : & + gwavef_alltoall_loc(1,ideb_loc:ifin_loc)
2157 : gwavef_alltoall(2,idebc:ifinc) = gwavef_alltoall_sym(2,idebe:ifine) &
2158 1031808 : & - gwavef_alltoall_loc(2,ideb_loc:ifin_loc)
2159 : end if
2160 :
2161 : end do
2162 :
2163 : !We divise by two
2164 130999296 : gwavef_alltoall(:,:) = gwavef_alltoall(:,:)/2
2165 :
2166 : !-----------------------
2167 : !Desallocation
2168 : !-----------------------
2169 :
2170 12576 : ABI_FREE(sendcounts_sym_loc)
2171 12576 : ABI_FREE(recvcounts_sym_loc)
2172 12576 : ABI_FREE(sdispls_sym_loc)
2173 12576 : ABI_FREE(rdispls_sym_loc)
2174 :
2175 12576 : ABI_FREE(gwavef_alltoall_loc)
2176 12576 : ABI_FREE(gwavef_alltoall_rcv)
2177 :
2178 12576 : end subroutine prep_wavef_sym_undo
2179 : !!***
2180 :
2181 : !!****f* ABINIT/prep_index_wavef_bandpp
2182 : !! NAME
2183 : !! prep_index_wavef_bandpp
2184 : !!
2185 : !! FUNCTION
2186 : !! this routine sorts the waves functions by bandpp and by processors
2187 : !! after the alltoall
2188 : !!
2189 : !! INPUTS
2190 : !! nproc_band = number of processors below the band
2191 : !! bandpp = number of groups of couple of waves functions
2192 : !! nspinor = number of spin
2193 : !! ndatarecv = total number of values received by the processor and sended
2194 : !! by the other processors band
2195 : !! recvcounts = number of values sended by each processor band and received
2196 : !! by the processor
2197 : !! rdispls = positions of the values received by the processor and
2198 : !! sended by each processor band
2199 : !!
2200 : !! OUTPUT
2201 : !! index_wavef_band = position of the sorted values
2202 : !!
2203 : !! SOURCE
2204 :
2205 72396 : subroutine prep_index_wavef_bandpp(nproc_band,bandpp,&
2206 : nspinor,ndatarecv,&
2207 72396 : recvcounts,rdispls,&
2208 : index_wavef_band)
2209 :
2210 : !Arguments ------------------------------------
2211 : !scalars
2212 : integer,intent(in) :: bandpp,ndatarecv,nproc_band,nspinor
2213 : !arrays
2214 : integer,intent(in) :: rdispls(nproc_band),recvcounts(nproc_band)
2215 : integer,allocatable,intent(out) :: index_wavef_band(:)
2216 :
2217 : !Local variables-------------------------------
2218 : !scalars
2219 : integer :: delta,idebc,idebe,ifinc,ifine,iindex,iproc,kbandpp,nb
2220 :
2221 : ! *********************************************************************
2222 :
2223 : !DEBUG
2224 : !write(std_out,*)' prep_index_wavef_banpp : enter '
2225 : !write(std_out,*) 'ndatarecv = ', ndatarecv
2226 : !write(std_out,*) 'rdispls(:) = ', rdispls(:)
2227 : !write(std_out,*) 'recvcounts(:) = ', recvcounts(:)
2228 : !ENDDEBUG
2229 :
2230 :
2231 : !---------------------------------------------
2232 : !Allocation
2233 : !---------------------------------------------
2234 217188 : ABI_MALLOC(index_wavef_band ,(bandpp*nspinor*ndatarecv))
2235 157382596 : index_wavef_band(:) =0
2236 :
2237 : !---------------------------------------------
2238 : !Calcul : loops on bandpp and processors band
2239 : !---------------------------------------------
2240 315316 : nb = sum(recvcounts(1:nproc_band))
2241 364706 : do kbandpp=1,bandpp
2242 :
2243 1214184 : do iproc=1,nproc_band
2244 :
2245 849478 : idebe = (rdispls(iproc) + 1) + (kbandpp-1) * ndatarecv*nspinor
2246 849478 : ifine = idebe + recvcounts(iproc) -1
2247 :
2248 849478 : if (iproc==1) then
2249 292310 : idebc = (kbandpp-1)* recvcounts(iproc)*nspinor + 1
2250 : else
2251 : idebc = (bandpp) * sum(recvcounts(1:iproc-1))*nspinor &
2252 : + (kbandpp-1)* recvcounts(iproc)*nspinor &
2253 1540048 : + 1
2254 : end if
2255 849478 : ifinc = idebc + recvcounts(iproc) -1
2256 311221500 : index_wavef_band(idebe:ifine) = (/( iindex,iindex=idebc,ifinc)/)
2257 849478 : delta=ifine-idebe
2258 1141788 : if (nspinor==2) then
2259 5250560 : index_wavef_band(idebe+nb :idebe+nb +delta)=(/( iindex,iindex=ifinc+1,ifinc+1+delta)/)
2260 : end if
2261 : end do
2262 : end do
2263 :
2264 72396 : end subroutine prep_index_wavef_bandpp
2265 : !!***
2266 :
2267 : !!****f* ABINIT/prep_sort_wavef_spin
2268 : !! NAME
2269 : !! prep_sort_wavef_spin
2270 : !!
2271 : !! FUNCTION
2272 : !! Compute index used to sort a spinorial wave-function by spin
2273 : !! Sort to have all nspinor=1 fisrt, then all nspinor=2
2274 : !!
2275 : !! INPUTS
2276 : !! nproc_band=size of "band" communicator
2277 : !! nspinor=number of spinorial components of the wavefunction
2278 : !! ndatarecv=total number of values on all processors
2279 : !! recvcounts(nproc_band)= number of received values by the processor
2280 : !! rdispls(nproc_band)= offsets of the received values by the processor
2281 : !!
2282 : !! OUTPUT
2283 : !! index_wavef(:)=array containing the sorted indexes (pointer, allocated in this routine)
2284 : !!
2285 : !! SOURCE
2286 :
2287 7368 : subroutine prep_sort_wavef_spin(nproc_band,nspinor,ndatarecv,recvcounts,rdispls,index_wavef)
2288 :
2289 : !Arguments ------------------------------------
2290 : !scalars
2291 : integer,intent(in) :: ndatarecv,nproc_band,nspinor
2292 : !arrays
2293 : integer,intent(in) :: rdispls(nproc_band),recvcounts(nproc_band)
2294 : integer,allocatable,intent(out) :: index_wavef(:)
2295 :
2296 : !Local variables-------------------------------
2297 : !scalars
2298 : integer :: isft,isft1,iproc,iindex
2299 : !arrays
2300 7368 : integer,allocatable :: recvcountsloc(:),rdisplsloc(:)
2301 :
2302 : ! *********************************************************************
2303 :
2304 22104 : ABI_MALLOC(index_wavef,(ndatarecv*nspinor))
2305 :
2306 22104 : ABI_MALLOC(recvcountsloc,(nproc_band))
2307 14736 : ABI_MALLOC(rdisplsloc,(nproc_band))
2308 22584 : recvcountsloc(:)=recvcounts(:)*2*nspinor
2309 22584 : rdisplsloc(:)=rdispls(:)*2*nspinor
2310 :
2311 : !---------------------------------------------
2312 : !Loops on bandpp and processors band
2313 : !---------------------------------------------
2314 22584 : isft=0
2315 22584 : do iproc=1,nproc_band
2316 :
2317 : ! ===== Spin up
2318 15216 : if (iproc==1) then
2319 : isft= 0
2320 : else
2321 23544 : isft= sum(recvcounts(1: (iproc-1)))
2322 : end if
2323 15216 : isft1 = 0.5*rdisplsloc(iproc)
2324 :
2325 : index_wavef(1+isft:isft+recvcounts(iproc))= &
2326 2149520 : & (/(iindex,iindex=isft1+1,isft1+recvcounts(iproc))/)
2327 :
2328 : ! =====Spin down
2329 15216 : if (iproc==1)then
2330 22584 : isft=sum(recvcounts(1:nproc_band))
2331 : else
2332 : isft=sum(recvcounts(1:nproc_band)) &
2333 54936 : & +sum(recvcounts(1:iproc-1))
2334 : end if
2335 15216 : isft1 = 0.5 * rdisplsloc(iproc) + recvcounts(iproc)
2336 :
2337 : index_wavef(1+isft:isft+recvcounts(iproc))= &
2338 2156888 : & (/(iindex,iindex=isft1+1,isft1+ recvcounts(iproc))/)
2339 :
2340 : end do
2341 :
2342 7368 : ABI_FREE(recvcountsloc)
2343 7368 : ABI_FREE(rdisplsloc)
2344 :
2345 7368 : end subroutine prep_sort_wavef_spin
2346 : !!***
2347 :
2348 : end module m_prep_kgb
2349 : !!***
|