Branch data Line data Source code
1 : : !!****m* ABINIT/m_gemm_nonlop
2 : : !! NAME
3 : : !! m_gemm_nonlop
4 : : !!
5 : : !! FUNCTION
6 : : !! This module provides functions to compute the nonlocal operator by means of the BLAS GEMM
7 : : !! routine. By treating ndat simultaneous wavefunctions, it is able to exploit BLAS3 routines,
8 : : !! which leads to excellent CPU efficiency and OpenMP scalability.
9 : : !!
10 : : !! COPYRIGHT
11 : : !! Copyright (C) 2014-2026 ABINIT group (AL,MS)
12 : : !! This file is distributed under the terms of the
13 : : !! GNU General Public License, see ~abinit/COPYING
14 : : !! or http://www.gnu.org/copyleft/gpl.txt .
15 : : !!
16 : : !! SOURCE
17 : :
18 : : ! TODO list :
19 : : ! Don't allocate the full nkpt structures, only those that are treated by this proc: use same init as in m_bandfft_kpt
20 : : ! support more options (forces & stresses mostly)
21 : : ! Support RF/other computations (only GS right now)
22 : : ! handle the case where nloalg(2) < 0, ie no precomputation of ph3d
23 : : ! more systematic checking of the workflow (right now, only works if init/make/gemm/destroy, no multiple makes, etc)
24 : : ! Avoid allocating the complex matrix when istwfk > 1
25 : : ! Merge with chebfi's invovl
26 : :
27 : :
28 : : #if defined HAVE_CONFIG_H
29 : : #include "config.h"
30 : : #endif
31 : :
32 : : #include "abi_common.h"
33 : :
34 : : module m_gemm_nonlop
35 : :
36 : : use defs_basis
37 : : use m_errors
38 : : use m_abicore
39 : : use m_xmpi
40 : : use m_xomp
41 : : use m_gputk
42 : : use m_abi_linalg
43 : : use m_gemm_nonlop_projectors
44 : :
45 : : use defs_abitypes, only : MPI_type
46 : : use m_opernlc_ylm, only : opernlc_ylm
47 : : use m_opernlc_ylm_allwf, only : opernlc_ylm_allwf
48 : : use m_opernla_gemm, only : opernla_gemm
49 : : use m_opernlb_gemm, only : opernlb_gemm
50 : : use m_opernld_ylm_allwf, only : opernld_ylm_allwf
51 : : use m_opernld_ylm, only : opernld_ylm
52 : : use m_pawcprj, only : pawcprj_type
53 : : use m_geometry, only : strconv
54 : : use m_kg, only : mkkpg
55 : : use m_hamiltonian, only : KPRIME_H_K, K_H_KPRIME, K_H_K, KPRIME_H_KPRIME
56 : :
57 : : #if defined(HAVE_GPU)
58 : : use m_gpu_toolbox
59 : : #endif
60 : :
61 : : #ifdef HAVE_FC_ISO_C_BINDING
62 : : use, intrinsic :: iso_c_binding, only : c_int32_t, c_int64_t, c_float, c_double, c_size_t, c_loc, c_ptr
63 : : #endif
64 : :
65 : :
66 : : implicit none
67 : :
68 : : private
69 : :
70 : : public :: gemm_nonlop
71 : :
72 : : ! Those routines are here to assess memory requirements
73 : : public :: gemm_nonlop_ompgpu_work_mem
74 : : public :: gemm_nonlop_ompgpu_static_mem
75 : : !!***
76 : :
77 : : !----------------------------------------------------------------------
78 : :
79 : :
80 : : contains
81 : :
82 [ # # ]: 0 : function gemm_nonlop_ompgpu_work_mem(istwfk, ndat, ngrads, npw, indlmn, nattyp, ntypat, lmnmax, signs, wfoptalg) result(req_mem)
83 : :
84 : : integer, intent(in) :: istwfk, ndat, ngrads, npw, ntypat, lmnmax, signs, wfoptalg
85 : : integer, intent(in) :: indlmn(:,:,:), nattyp(ntypat)
86 : :
87 : : integer :: nprojs, cplex, itypat
88 : : real(dp) :: req_mem
89 : :
90 : : ! *************************************************************************
91 : :
92 [ # # ]: 0 : cplex=2;if (istwfk>1) cplex=1
93 : 0 : nprojs=0
94 [ # # ]: 0 : do itypat=1,ntypat
95 [ # # # # ]: 0 : nprojs = nprojs + count(indlmn(3,:,itypat)>0)*nattyp(itypat)
96 : : end do
97 : :
98 : 0 : req_mem = 0
99 : :
100 [ # # ]: 0 : if(cplex == 1) then
101 : 0 : req_mem = req_mem + dp * int(npw, c_size_t) * ndat ! temp_realvec_r
102 : 0 : req_mem = req_mem + dp * int(npw, c_size_t) * ndat ! temp_realvec_i
103 : : end if
104 : :
105 : 0 : req_mem = req_mem + dp * lmnmax * (lmnmax+1)/2 * ntypat ! sij_typ
106 : :
107 : 0 : req_mem = req_mem + dp * cplex * int(nprojs, c_size_t) * int(ndat, c_size_t) ! projections
108 : 0 : req_mem = req_mem + dp * cplex * int(nprojs, c_size_t) * int(ndat, c_size_t) ! s_projections
109 : 0 : req_mem = req_mem + dp * cplex * int(nprojs, c_size_t) * int(ndat, c_size_t) ! vnl_projections
110 : :
111 : : ! Not in a place where vectin, vectout, svectout, enlout are allocated
112 [ # # ]: 0 : if(wfoptalg<0) then
113 : 0 : req_mem = req_mem + dp * cplex * int(npw, c_size_t) * int(ndat, c_size_t) ! vectin
114 [ # # ]: 0 : if(signs==2) then
115 : 0 : req_mem = req_mem + dp * cplex * int(npw, c_size_t) * int(ndat, c_size_t) ! vectout
116 : 0 : req_mem = req_mem + dp * cplex * int(npw, c_size_t) * int(ndat, c_size_t) ! svectout
117 : : end if
118 [ # # ]: 0 : if(signs==1) then
119 : 0 : req_mem = req_mem + dp * cplex * nprojs * int(ndat, c_size_t) ! enlout (overestimate)
120 : : end if
121 : : end if
122 : :
123 [ # # ]: 0 : if(ngrads>0) then
124 : 0 : req_mem = req_mem + dp * cplex * ngrads * int(nprojs, c_size_t) * int(ndat, c_size_t) ! dprojections
125 [ # # ]: 0 : if(signs==2) then
126 : 0 : req_mem = req_mem + dp * cplex * ngrads * int(nprojs, c_size_t) * int(ndat, c_size_t) ! s_dprojections
127 : 0 : req_mem = req_mem + dp * cplex * ngrads * int(nprojs, c_size_t) * int(ndat, c_size_t) ! vnl_dprojections
128 : : end if
129 : : end if
130 : :
131 : 0 : end function gemm_nonlop_ompgpu_work_mem
132 : :
133 : : !----------------------------------------------------------------------
134 : :
135 [ # # ]: 0 : function gemm_nonlop_ompgpu_static_mem(npw, indlmn, nattyp, ntypat, mpi_block_size, ngrads, use_distrib) result(req_mem)
136 : :
137 : : integer, intent(in) :: npw, ntypat, mpi_block_size, ngrads
138 : : integer, intent(in) :: indlmn(:,:,:), nattyp(ntypat)
139 : : logical, intent(in) :: use_distrib
140 : :
141 : : integer :: nprojs, nprojs_last_blk, itypat
142 : : integer(kind=c_size_t) :: req_mem
143 : :
144 : : ! *************************************************************************
145 : :
146 : 0 : nprojs = 0
147 [ # # ]: 0 : do itypat=1,ntypat
148 [ # # # # ]: 0 : nprojs = nprojs + count(indlmn(3,:,itypat)>0)*nattyp(itypat)
149 : : end do
150 : 0 : nprojs_last_blk = nprojs / mpi_block_size + modulo(nprojs,mpi_block_size)
151 : :
152 : 0 : req_mem = 0
153 : :
154 [ # # # # ]: 0 : if(mpi_block_size>1 .and. use_distrib) then
155 : 0 : req_mem = req_mem + dp * 2 * int(npw, c_size_t) * int(nprojs_last_blk, c_size_t) !projs_recv
156 : : #ifdef HAVE_GPU_MPI
157 : : if(ngrads==0) then
158 : : ! Add a suspected internal buffer for GPU-aware MPI (no derivatives)
159 : : req_mem = req_mem + dp * 2 * int(npw, c_size_t) * int(nprojs_last_blk, c_size_t) !projs_recv
160 : : end if
161 : : #endif
162 : : end if
163 : : ! projs or projs_r + projs_i
164 : 0 : req_mem = req_mem + 2 * dp * int(npw, c_size_t) * int(nprojs_last_blk, c_size_t)
165 [ # # ]: 0 : if(ngrads>0) then
166 : : ! dprojs or dprojs_r + dprojs_i
167 : 0 : req_mem = req_mem + 2 * dp * int(npw, c_size_t) * int(ngrads, c_size_t) * int(nprojs_last_blk, c_size_t)
168 [ # # # # ]: 0 : if(mpi_block_size>1 .and. use_distrib) then
169 : 0 : req_mem = req_mem + dp * 2 * int(npw, c_size_t) * int(ngrads, c_size_t)*int(nprojs_last_blk, c_size_t) !dprojs_recv
170 : : #ifdef HAVE_GPU_MPI
171 : : ! Add a suspected internal buffer for GPU-aware MPI (with derivatives)
172 : : req_mem = req_mem + dp * 2 * int(npw, c_size_t) * int(ngrads, c_size_t)*int(nprojs_last_blk, c_size_t) !dprojs_recv
173 : : #endif
174 : : end if
175 : : end if
176 : :
177 : 0 : end function gemm_nonlop_ompgpu_static_mem
178 : :
179 : : !----------------------------------------------------------------------
180 : :
181 : : !!****f* m_gemm_nonlop/gemm_nonlop
182 : : !! NAME
183 : : !! gemm_nonlop
184 : : !!
185 : : !! FUNCTION
186 : : !! Replacement of nonlop. same prototype as nonlop although not all options are implemented.
187 : : !!
188 : : !! INPUTS
189 : : !! [gpu_option] = GPU implementation to use, i.e. cuda, openMP, ... (0=not using GPU)
190 : : !!
191 : : !! SOURCE
192 [ - + ]: 14154 : subroutine gemm_nonlop(atindx1,choice,cpopt,cprjin,dimenl1,dimenl2,dimekbq,dimffnlin,dimffnlout,&
193 : 14154 : & enl,enl_ndat,enlout,ffnlin,ffnlout,gmet,gprimd,idir,indlmn,istwf_k,&
194 : 28308 : & kgin,kgout,kpgin,kpgout,kptin,kptout,lambda,lmnmax,matblk,mgfft,&
195 : 14154 : & mpi_enreg,natom,nattyp,ndat,ngfft,nkpgin,nkpgout,nloalg,&
196 : : & nnlout,npwin,npwout,nspinor,nspinortot,ntypat,only_SO,paw_opt,&
197 : 28308 : & ph3din,ph3dout,signs,sij,svectout,&
198 [ - + - + ]: 14154 : & tim_nonlop,ucvol,useylm,vectin,vectout,&
199 : 14154 : & atom_proj_shift,select_k,iatom_only,typat,usepaw,&
200 [ + + + - ]: 14154 : & vectproj,gpu_option)
201 : :
202 : : !Arguments ------------------------------------
203 : : !scalars
204 : : integer,intent(in) :: choice,cpopt,dimenl1,dimenl2,dimekbq,dimffnlin,dimffnlout,idir
205 : : integer,intent(in) :: istwf_k,lmnmax,matblk,mgfft,natom,ndat,nkpgin
206 : : integer,intent(in) :: nkpgout,nnlout,npwin,npwout,nspinor,nspinortot,ntypat,only_SO
207 : : integer,intent(in) :: paw_opt,signs,tim_nonlop,useylm,atom_proj_shift,select_k,iatom_only,usepaw
208 : : integer,optional,intent(in) :: gpu_option
209 : : real(dp),intent(in) :: lambda(ndat),ucvol
210 : : type(MPI_type),intent(in) :: mpi_enreg
211 : : !arrays
212 : : integer,intent(in),target :: atindx1(natom),indlmn(6,lmnmax,ntypat),kgin(3,npwin)
213 : : integer,intent(in),target :: kgout(3,npwout),nattyp(ntypat),ngfft(18),nloalg(3),typat(natom)
214 : : real(dp),intent(in),ABI_CONTIGUOUS target :: enl(:,:,:,:),enl_ndat(:,:,:,:,:)
215 : : real(dp),intent(in),target :: ffnlin(npwin,dimffnlin,lmnmax,ntypat)
216 : : real(dp),intent(in),target :: ffnlout(npwout,dimffnlout,lmnmax,ntypat),gmet(3,3)
217 : : real(dp),intent(in) :: gprimd(3,3),kptin(3),kptout(3)
218 : : real(dp),intent(in),target :: kpgin(npwin,nkpgin*useylm),kpgout(npwout,nkpgout*useylm)
219 : : real(dp),intent(in),target :: sij(dimenl1,ntypat*((paw_opt+1)/3))
220 : : real(dp),intent(inout),target :: ph3din(2,npwin,matblk),ph3dout(2,npwout,matblk)
221 : : real(dp),intent(inout),target :: vectin(2,npwin*nspinor*ndat)
222 : : real(dp),intent(inout) :: enlout(nnlout*ndat)
223 : : real(dp),intent(out), target :: svectout(:,:)
224 : : real(dp),intent(inout),target :: vectout(:,:)
225 : : real(dp),intent(inout),optional, ABI_CONTIGUOUS target :: vectproj(:,:,:)
226 : : type(pawcprj_type),intent(inout) :: cprjin(:,:)
227 : :
228 : : ! locals
229 : : integer :: ii, idat, igrad, nprojs, ngrads, ngrads2, shift, iatom, nlmn, ierr, ibeg, iend, ikin, ikout
230 : : integer :: cplex, cplex_enl, cplex_fac
231 : : integer :: nnlout_test
232 : : integer :: iatm, ndgxdt, ndgxdtfac, nd2gxdt, nd2gxdtfac, optder, itypat, ilmn
233 : 14154 : integer,allocatable :: cplex_dgxdt(:), cplex_d2gxdt(:)
234 : : logical :: local_vectproj,use_enl_ndat
235 : : real(dp) :: d2gxdt_dum_in(1,1,1,1,1), d2gxdt_dum_out(1,1,1,1,1),d2gxdt_dum_out2(1,1,1,1,1)
236 : 14154 : real(dp), allocatable :: sij_typ(:,:)
237 : 14154 : real(dp), ABI_CONTIGUOUS pointer :: projections(:,:,:)
238 : 14154 : real(dp), allocatable :: s_projections(:,:,:), vnl_projections(:,:,:)
239 : 14154 : real(dp), allocatable :: dprojections(:,:,:), temp_realvec_r(:), temp_realvec_i(:)
240 : 14154 : real(dp), allocatable, target :: s_dprojections(:,:,:), vnl_dprojections(:,:,:)
241 : 14154 : real(dp), allocatable, target :: d2projections(:,:,:)
242 : 14154 : real(dp), allocatable :: enlk(:),fnlk(:,:),ddkk(:,:),strnlk(:,:),gmet2(:,:)
243 : 14154 : real(dp), allocatable :: work1(:),work2(:),work3(:,:),work4(:,:),work5(:,:,:),work6(:,:,:),work7(:,:,:)
244 : : integer :: idbeg,idend,idfbeg,idfend,dshift,id2beg,id2end,d2shift,dfshift,enlout_shift,ndat_enl
245 : : real(dp) :: work(6)
246 : : integer :: ndgxdt_stored,ishift
247 : : integer :: mu0,ic,nu,mu,jc,mua,mub,nua1,nua2,nub1,nub2
248 : : integer,parameter :: alpha(6)=(/1,2,3,3,3,2/),beta(6)=(/1,2,3,2,1,1/)
249 : : integer,parameter :: gamma(3,3)=reshape((/1,6,5,6,2,4,5,4,3/),(/3,3/))
250 : : integer :: matblk_,natom_,ntypat_,ispden,dimenl2_,ia_beg,ia_end,dimsij,nkpgin_,nkpgout_
251 : 14154 : integer, ABI_CONTIGUOUS pointer :: atindx1_(:),indlmn_(:,:,:),nattyp_(:)
252 : 14154 : real(dp),pointer :: ffnlin_(:,:,:,:),ffnlout_(:,:,:,:)
253 : 14154 : real(dp),pointer :: ph3din_(:,:,:),ph3dout_(:,:,:)
254 : 14154 : real(dp), ABI_CONTIGUOUS pointer :: enl_(:,:,:,:,:)
255 : 14154 : real(dp), ABI_CONTIGUOUS pointer :: sij_(:,:)
256 : 14154 : real(dp), ABI_CONTIGUOUS pointer :: kpgin_(:,:),kpgout_(:,:)
257 : : logical :: nld_on_gpu
258 : :
259 : : logical :: transfer_vectin,transfer_vectout,transfer_svectout
260 : 14154 : real(dp), pointer :: vectin_(:,:),vectout_(:,:),svectout_(:,:)
261 : :
262 : : ! *************************************************************************
263 : :
264 : : ! We keep the same interface as nonlop, but we don't use many of those
265 : : ABI_UNUSED((/gmet/))
266 : : ABI_UNUSED((/mgfft/))
267 : : ABI_UNUSED((/nloalg,ngfft,only_SO,tim_nonlop/))
268 : :
269 : : ! Check supported options
270 : 14154 : if (.not.gemm_nonlop_use_gemm) then
271 : 0 : ABI_BUG('computation not prepared for gemm_nonlop use!')
272 : : end if
273 : : if ( (choice>3.and.choice/=7.and.choice/=5.and.choice/=51.and.signs==2) .or. &
274 [ - + - - : 14154 : & (choice>3.and.choice/=7.and.choice/=23.and.choice/=4.and.choice/=54.and.choice/=55.and.choice/=6.and.signs==1) .or. &
- - - - -
+ - - -
+ ]
275 : : & (useylm/=1) ) then
276 : 0 : ABI_BUG('gemm_nonlop option not supported!')
277 : : end if
278 [ + + ]: 14154 : if (signs==1) then
279 : 2676 : nnlout_test=0
280 [ + + ]: 2676 : if (choice==1) nnlout_test=1
281 [ + + ]: 2676 : if (choice==2) nnlout_test=3*natom
282 [ + + ]: 2676 : if (choice==3) nnlout_test=6
283 [ - + ]: 2676 : if (choice==23) nnlout_test=6+3*natom
284 [ - + ]: 2676 : if (nnlout<nnlout_test) then
285 : 0 : ABI_BUG('wrong nnlout size!')
286 : : end if
287 : : end if
288 : :
289 : 14154 : transfer_vectin=.false.; transfer_vectout=.false.; transfer_svectout=.false.
290 [ - + ]: 14154 : if(gpu_option==ABI_GPU_OPENMP) then
291 : : ! Check if provided buffers are already mapped on GPU
292 : : transfer_vectin=.not. xomp_target_is_present(c_loc(vectin)) &
293 : : .and. ((cpopt < 2 .and. choice < 2) .or. (cpopt <= 3 .and. choice >= 2) &
294 : 0 : .or. (choice/=7 .and.paw_opt >=3))
295 : : transfer_vectout=.not. xomp_target_is_present(c_loc(vectout)) &
296 : 0 : .and. (signs==2 .and. (paw_opt == 0 .or. paw_opt == 1 .or. paw_opt == 4))
297 : : transfer_svectout=.not. xomp_target_is_present(c_loc(svectout)) &
298 : 0 : .and. (signs==2 .and. (paw_opt == 3 .or. paw_opt == 4))
299 : : end if
300 : :
301 : 14154 : ikin=1; ikout=1;
302 : 14154 : select case (select_k)
303 : : case (K_H_K)
304 : : ikin=1; ikout=1;
305 : : case (K_H_KPRIME)
306 : : ikin=2; ikout=1;
307 : : case (KPRIME_H_K)
308 : : ikin=1; ikout=2;
309 : : case (KPRIME_H_KPRIME)
310 [ + - ]: 14154 : ikin=2; ikout=2;
311 : : end select
312 [ + + ]: 14154 : cplex=2;if (istwf_k>1) cplex=1
313 [ + + ]: 14154 : cplex_enl=1;if (paw_opt>0) cplex_enl=2*dimenl1/(lmnmax*(lmnmax+1)) ! is enl complex?
314 : 14154 : cplex_fac=max(cplex,dimekbq)
315 [ + - - + : 14154 : if ((nspinortot==2.or.cplex_enl==2).and.paw_opt>0.and.choice/=7) cplex_fac=2 ! is vnl_projections complex?
- - - - ]
316 [ + + + - ]: 84924 : use_enl_ndat=.false. ; if (size(enl_ndat)>0) use_enl_ndat=.true.
317 : 14154 : ndat_enl=1; if(use_enl_ndat) ndat_enl=ndat
318 : :
319 : : ! Processing one atom : set pointers to atom-specific arrays (for opernlc)
320 [ - + ]: 14154 : if(iatom_only > 0) then
321 : 0 : iatm=atindx1(iatom_only);itypat=typat(iatom_only)
322 : 0 : ia_beg=iatom_only; ia_end=iatom_only
323 : 0 : natom_=1 ; ntypat_=1 ; dimenl2_=1 ; matblk_=1
324 [ # # ]: 0 : ABI_MALLOC(atindx1_,(1))
325 [ # # ]: 0 : ABI_MALLOC(nattyp_,(1))
326 : 0 : atindx1_(1)=1 ; nattyp_(1)=1
327 [ # # # # : 0 : ABI_MALLOC(ph3din_,(2,npwin,1))
# # # # #
# # # ]
328 [ # # # # : 0 : ABI_MALLOC(ph3dout_,(2,npwout,1))
# # # # #
# # # ]
329 [ # # # # : 0 : ph3din_(:,1:npwin,1)=ph3din(:,1:npwin,iatm)
# # # # #
# ]
330 [ # # # # : 0 : ph3dout_(:,1:npwout,1)=ph3dout(:,1:npwout,iatm)
# # # # #
# ]
331 [ # # # # : 0 : ABI_MALLOC(ffnlin_,(npwin,dimffnlin,lmnmax,1))
# # # # #
# # # # #
# # # # #
# ]
332 [ # # # # : 0 : ABI_MALLOC(ffnlout_,(npwout,dimffnlout,lmnmax,1))
# # # # #
# # # # #
# # # # #
# ]
333 [ # # # # : 0 : ffnlin_(:,:,:,1)=ffnlin(:,:,:,itypat)
# # # # #
# # # #
# ]
334 [ # # # # : 0 : ffnlout_(:,:,:,1)=ffnlout(:,:,:,itypat)
# # # # #
# # # #
# ]
335 [ # # # # : 0 : ABI_MALLOC(indlmn_,(6,lmnmax,1))
# # # # #
# # # ]
336 [ # # # # : 0 : indlmn_(:,:,1)=indlmn(:,:,itypat)
# # # # #
# ]
337 [ # # # # ]: 0 : if (size(sij)>0) then
338 : 0 : dimsij=size(sij,1)
339 [ # # # # : 0 : ABI_MALLOC(sij_,(dimsij,1))
# # # # #
# # # ]
340 [ # # ]: 0 : if (size(sij,2)==ntypat) then
341 [ # # # # : 0 : sij_(:,1)=sij(:,itypat)
# # ]
342 [ # # # # ]: 0 : else if (size(sij)>0) then
343 [ # # # # : 0 : sij_(:,1)=sij(:,1)
# # ]
344 : : end if
345 : : end if
346 [ # # # # ]: 0 : if (size(enl_ndat)>0) then
347 [ # # # # : 0 : ABI_MALLOC(enl_,(size(enl_ndat,1),1,nspinor**2,ndat,size(enl_ndat,5)))
# # # # #
# # # # #
# # # # #
# # # #
# ]
348 [ # # ]: 0 : do idat=1,ndat
349 [ # # ]: 0 : do ii=1,size(enl_ndat,5)
350 [ # # ]: 0 : do ispden=1,nspinor**2
351 [ # # # # ]: 0 : if (dimenl2==natom .and. usepaw==1) then
352 [ # # # # : 0 : enl_(:,1,ispden,idat,ii)=enl_ndat(:,iatom_only,ispden,idat,ii)
# # ]
353 [ # # ]: 0 : else if (dimenl2==ntypat) then
354 [ # # # # : 0 : enl_(:,1,ispden,idat,ii)=enl_ndat(:,itypat,ispden,idat,ii)
# # ]
355 : : else
356 [ # # # # : 0 : enl_(:,1,ispden,idat,ii)=enl_ndat(:,1,ispden,idat,ii)
# # ]
357 : : end if
358 : : end do
359 : : end do
360 : : end do
361 [ # # # # ]: 0 : else if (size(enl)>0) then
362 [ # # # # : 0 : ABI_MALLOC(enl_,(size(enl,1),1,nspinor**2,size(enl,4),1))
# # # # #
# # # # #
# # # # #
# ]
363 [ # # ]: 0 : do ii=1,size(enl,4)
364 [ # # ]: 0 : do ispden=1,nspinor**2
365 [ # # # # ]: 0 : if (dimenl2==natom .and. usepaw==1) then
366 [ # # # # : 0 : enl_(:,1,ispden,ii,1)=enl(:,iatom_only,ispden,ii)
# # ]
367 [ # # ]: 0 : else if (dimenl2==ntypat) then
368 [ # # # # : 0 : enl_(:,1,ispden,ii,1)=enl(:,itypat,ispden,ii)
# # ]
369 : : else
370 [ # # # # : 0 : enl_(:,1,ispden,ii,1)=enl(:,1,ispden,ii)
# # ]
371 : : end if
372 : : end do
373 : : end do
374 : : else
375 [ # # ]: 0 : ABI_MALLOC(enl_,(0,0,0,0,0))
376 : : end if
377 : :
378 : : ! Usual case : all atoms are processed
379 : : else
380 : 14154 : natom_ =natom; ntypat_=ntypat
381 : 14154 : ia_beg=1; ia_end=natom
382 : 14154 : dimenl2_=dimenl2 ; matblk_=matblk
383 : 14154 : atindx1_ => atindx1
384 : 14154 : nattyp_ => nattyp
385 : 14154 : ffnlin_ => ffnlin
386 : 14154 : ffnlout_ => ffnlout
387 : 14154 : enl_(1:dimenl1,1:dimenl2,1:nspinortot**2,1:dimekbq,1:1) => enl(:,:,:,:)
388 [ - + ]: 14154 : if(use_enl_ndat) then
389 : 0 : enl_ => enl_ndat
390 : : end if
391 : 14154 : sij_ => sij
392 : 14154 : indlmn_ => indlmn
393 : 14154 : ph3din_ => ph3din
394 : 14154 : ph3dout_ => ph3dout
395 : : end if
396 : :
397 : : ! The number of projectors used for computation may vary among
398 : : ! nonlop calls, from computing on all atoms to a select one for
399 : : ! some perturbations.
400 : : ! In such cases, projs arrays must be recomputed
401 : 14154 : nprojs=0
402 [ + + ]: 37718 : do itypat=1,ntypat_
403 [ + + + + ]: 414430 : nprojs = nprojs + count(indlmn_(3,:,itypat)>0)*nattyp_(itypat)
404 : : end do
405 : :
406 [ - + ]: 14154 : if(nprojs == 0) then
407 : : ! TODO check if this is correct
408 [ # # ]: 0 : if (iatom_only>0) then
409 [ # # ]: 0 : ABI_FREE(atindx1_)
410 [ # # ]: 0 : ABI_FREE(nattyp_)
411 [ # # ]: 0 : ABI_FREE(ph3din_)
412 [ # # ]: 0 : ABI_FREE(ph3dout_)
413 [ # # ]: 0 : ABI_FREE(ffnlin_)
414 [ # # ]: 0 : ABI_FREE(ffnlout_)
415 [ # # ]: 0 : ABI_FREE(enl_)
416 [ # # ]: 0 : ABI_FREE(indlmn_)
417 [ # # # # ]: 0 : if (size(sij) > 1) then
418 [ # # ]: 0 : ABI_FREE(sij_)
419 : : end if
420 : : end if
421 [ # # ]: 0 : if(signs == 1) then
422 [ # # ]: 0 : enlout=zero
423 : : return
424 : : end if
425 [ # # ]: 0 : if(signs == 2) then
426 [ # # ]: 0 : if(gpu_option==ABI_GPU_DISABLED) then
427 [ # # # # ]: 0 : vectout = zero
428 [ # # # # : 0 : if(paw_opt>0) svectout = vectin
# # # # #
# # # ]
429 : : else if(gpu_option==ABI_GPU_OPENMP) then
430 : : #ifdef HAVE_OPENMP_OFFLOAD
431 : : if(transfer_vectout) then
432 : : vectout = zero
433 : : else
434 : : call gpu_set_to_zero(vectout, int(2,c_size_t) * npwout * nspinor * ndat)
435 : : end if
436 : : if(paw_opt>0) then
437 : : if(transfer_svectout .and. transfer_vectin) then
438 : : svectout = vectin
439 : : else if(transfer_vectin) then
440 : : svectout = vectin
441 : : !$OMP TARGET UPDATE TO(svectout)
442 : : else if(transfer_svectout) then
443 : : !$OMP TARGET UPDATE FROM(vectin)
444 : : svectout = vectin
445 : : else
446 : : call gpu_copy(svectout, vectin, int(2,c_size_t) * npwin * nspinor * ndat)
447 : : end if
448 : : end if
449 : : #endif
450 : : end if
451 : 0 : return
452 : : end if
453 : : end if
454 : :
455 : : !Eventually re-compute (k+G) vectors (and related data)
456 : 14154 : nkpgin_=0
457 [ + + ]: 14154 : if (choice==2.or.choice==54) nkpgin_=3
458 [ + + ]: 14154 : if (signs==1) then
459 [ - + ]: 2676 : if (choice==4) nkpgin_=9
460 [ + + ]: 2676 : if (choice==3.or.choice==23.or.choice==6) nkpgin_=3
461 [ - + ]: 2676 : if (choice==55) nkpgin_=3
462 : : end if
463 [ + + ]: 14154 : if (nkpgin<nkpgin_) then
464 [ - + + - : 256 : ABI_MALLOC(kpgin_,(npwin,nkpgin_))
- + + - +
- + - - +
- + ]
465 : 64 : call mkkpg(kgin,kpgin_,kptin,nkpgin_,npwin)
466 : : else
467 : 14090 : nkpgin_ = nkpgin
468 : 14090 : kpgin_ => kpgin
469 : : end if
470 : :
471 : 14154 : nkpgout_=0
472 [ + + - + ]: 14154 : if ((choice==2.or.choice==3.or.choice==54).and.signs==2) nkpgout_=3
473 [ - + ]: 14154 : if (nkpgout<nkpgout_) then
474 [ # # # # : 0 : ABI_MALLOC(kpgout_,(npwout,nkpgout_))
# # # # #
# # # # #
# # ]
475 : 0 : call mkkpg(kgout,kpgout_,kptout,nkpgout_,npwout)
476 : : else
477 : 14154 : nkpgout_ = nkpgout
478 : 14154 : kpgout_ => kpgout
479 : : end if
480 : :
481 : : #ifdef HAVE_OPENMP_OFFLOAD
482 : : !$OMP TARGET ENTER DATA MAP(to:kpgin_) if(nkpgin_ > 0 .and. gpu_option==ABI_GPU_OPENMP)
483 : : !$OMP TARGET ENTER DATA MAP(to:kpgout_) if(nkpgout_ > 0 .and. gpu_option==ABI_GPU_OPENMP)
484 : :
485 : : ! Allocate and copy GPU buffers if user doesn't manage them
486 : : !$OMP TARGET ENTER DATA MAP(to:vectin) IF(transfer_vectin)
487 : : !$OMP TARGET ENTER DATA MAP(alloc:vectout) IF(transfer_vectout)
488 : : !$OMP TARGET ENTER DATA MAP(alloc:svectout) IF(transfer_svectout)
489 : :
490 : : !$OMP TARGET ENTER DATA MAP(to:atindx1,indlmn) IF(gpu_option==ABI_GPU_OPENMP)
491 : : if(size(enl_)>0) then
492 : : !$OMP TARGET ENTER DATA MAP(to:enl_) IF(gpu_option==ABI_GPU_OPENMP)
493 : : end if
494 : : #endif
495 : :
496 : : !FIXME These seemingly useless pointers are used in BLAS operations for
497 : : ! working around a bug in AOMP LLVM misreading mapped device pointers.
498 : : ! I chose to generalise the workaround to avoid dupplicating each
499 : : ! BLAS call specifically for handling AOMP LLVM.
500 : 14154 : vectin_ => vectin
501 : 14154 : vectout_ => vectout
502 : 14154 : svectout_ => svectout
503 : :
504 : : ! If vectproj is provided, use it for further calculations, use allocated array otherwise
505 : 14154 : local_vectproj=.false.
506 [ + + ]: 14154 : if(PRESENT(vectproj)) then
507 [ + + + - ]: 4608 : if(size(vectproj)>1) local_vectproj=.true.
508 : : end if
509 : 1152 : if (local_vectproj) projections => vectproj
510 : :
511 : :
512 [ + + + + ]: 14154 : if(signs == 1 .and. choice > 0) then
513 [ + + ]: 18568 : enlout=zero
514 [ - + + - : 1560 : ABI_MALLOC(enlk,(ndat))
+ - + - -
+ - + ]
515 [ + + ]: 2824 : enlk=zero
516 [ + - - + : 2080 : ABI_MALLOC(fnlk,(3*natom,ndat))
+ - - + +
- + - + -
- + - + ]
517 [ + + + + ]: 48904 : fnlk=zero
518 [ - + + - : 1560 : ABI_MALLOC(ddkk,(6,ndat))
+ - + - -
+ - + -
+ ]
519 [ + + + + ]: 16648 : ddkk=zero
520 [ - + + - : 1040 : ABI_MALLOC(strnlk,(6,ndat))
- + - + ]
521 [ + + + + ]: 16648 : strnlk=zero
522 : : #ifdef HAVE_OPENMP_OFFLOAD
523 : : !$OMP TARGET ENTER DATA MAP(to:enlout,enlk,fnlk,ddkk,strnlk) IF(gpu_option==ABI_GPU_OPENMP)
524 : : #endif
525 : : end if
526 : :
527 [ + + + + : 14154 : if(paw_opt>=2 .and. choice > 0 .and. choice /= 7) then
+ + ]
528 [ + - - + : 34424 : ABI_MALLOC(sij_typ,(lmnmax*(lmnmax+1)/2,ntypat))
+ - - + +
- + - + -
- + - + ]
529 [ + - ]: 8606 : if (cplex_enl==1) then
530 [ + + ]: 22910 : do itypat=1, ntypat_
531 [ + + + - ]: 242696 : nlmn=count(indlmn_(3,:,itypat)>0)
532 [ + + ]: 2076314 : do ilmn=1,nlmn*(nlmn+1)/2
533 : 2067708 : sij_typ(ilmn,itypat)=sij_(ilmn,itypat)
534 : : end do
535 : : end do
536 : : else
537 [ # # ]: 0 : do itypat=1, ntypat_
538 [ # # # # ]: 0 : nlmn=count(indlmn_(3,:,itypat)>0)
539 [ # # ]: 0 : do ilmn=1,nlmn*(nlmn+1)/2
540 : 0 : sij_typ(ilmn,itypat)=sij_(2*ilmn-1,itypat)
541 : : end do
542 : : end do
543 : : end if
544 : : #ifdef HAVE_OPENMP_OFFLOAD
545 : : !$OMP TARGET ENTER DATA MAP(to:sij_typ) IF(gpu_option==ABI_GPU_OPENMP)
546 : : #endif
547 : : else
548 [ - + + - : 16644 : ABI_MALLOC(sij_typ,(1,ntypat)) ! Dummy alloc
+ - + - -
+ - + ]
549 : : end if
550 : :
551 : 14154 : ndgxdt = -1
552 : 14154 : nd2gxdt = -1
553 : :
554 : 14154 : ndgxdtfac = 0; nd2gxdtfac = 0
555 [ + + ]: 14154 : if (choice==2) then
556 [ + - ]: 212 : if (signs==1) ndgxdt=3
557 [ - + ]: 212 : if (signs==2) ndgxdt=1
558 [ - + ]: 212 : if (signs==2) ndgxdtfac=1
559 : : end if
560 [ - + ]: 14154 : if (choice==22) then
561 [ # # ]: 0 : if (signs==2) ndgxdtfac=1
562 : : end if
563 [ - + ]: 14154 : if (choice==23) then
564 [ # # ]: 0 : if (signs==1) ndgxdt=9
565 : : end if
566 [ + + ]: 14154 : if (choice==3) then
567 [ + - ]: 212 : if (signs==1) ndgxdt=6
568 [ - + ]: 212 : if (signs==2) ndgxdt=1
569 [ - + ]: 212 : if (signs==2) ndgxdtfac=1
570 : : end if
571 [ - + ]: 14154 : if (choice==4) then
572 [ # # ]: 0 : if(signs==1) ndgxdt=3
573 [ # # ]: 0 : if(signs==1) ndgxdtfac=3
574 [ # # ]: 0 : if(signs==1) nd2gxdt=6
575 : : end if
576 [ - + ]: 14154 : if (choice==5) then
577 [ # # ]: 0 : if(signs==1) ndgxdt=3
578 [ # # ]: 0 : if(signs==2) ndgxdt=1
579 [ # # ]: 0 : if(signs==2) ndgxdtfac=1
580 : : end if
581 [ - + ]: 14154 : if (choice==51) then
582 [ # # ]: 0 : if(signs==1) ndgxdt=3
583 [ # # ]: 0 : if(signs==2) ndgxdt=1
584 [ # # ]: 0 : if(signs==2) ndgxdtfac=1
585 : : end if
586 [ - + ]: 14154 : if (choice==54) then
587 [ # # ]: 0 : if(signs==1) ndgxdt=6
588 [ # # ]: 0 : if(signs==1) ndgxdtfac=6
589 [ # # ]: 0 : if(signs==1) nd2gxdt=9
590 [ # # ]: 0 : if(signs==2) ndgxdt=1
591 [ # # ]: 0 : if(signs==2) nd2gxdt=1
592 [ # # ]: 0 : if(signs==2) ndgxdtfac=1
593 [ # # ]: 0 : if(signs==2) nd2gxdtfac=1
594 : : end if
595 [ - + ]: 14154 : if (choice==55) then
596 [ # # ]: 0 : if(signs==1) ndgxdt=9
597 [ # # ]: 0 : if(signs==1) ndgxdtfac=9
598 [ # # ]: 0 : if(signs==1) nd2gxdt=18
599 : : end if
600 [ - + ]: 14154 : if (choice==6) then
601 [ # # ]: 0 : if(signs==1) ndgxdt=9
602 [ # # ]: 0 : if(signs==1) ndgxdtfac=9
603 [ # # ]: 0 : if(signs==1) nd2gxdt=54
604 : : end if
605 : 14154 : ngrads=0; ngrads2=0
606 [ + + ]: 14154 : if(ndgxdt>0) ngrads=ndgxdt; if(ndgxdt>0) ngrads2=nd2gxdt
607 [ + + ]: 14154 : if(ndgxdt>0) then
608 [ - + ]: 424 : ABI_CHECK(ndgxdtfac<=ndgxdt,"BUG: ndgxdtfac>ndgxdt!")
609 : : end if
610 [ - + ]: 14154 : optder = 0;if (ndgxdtfac>0) optder = 1
611 [ - + ]: 14154 : if (nd2gxdtfac>0) optder=2
612 [ + + + - : 42462 : ABI_MALLOC(cplex_dgxdt, (ndgxdt))
+ - + + -
+ - + ]
613 [ + - - - : 42462 : ABI_MALLOC(cplex_d2gxdt,(nd2gxdt))
+ - - + -
+ - + ]
614 [ + + - + ]: 16062 : cplex_dgxdt(:) = 1 ; cplex_d2gxdt(:) = 1
615 : : ! When istwf_k > 1, gx derivatives can be real or pure imaginary
616 : : ! cplex_dgxdt(i) = 1 if dgxdt(1,i,:,:) is real, 2 if it is pure imaginary
617 : : ! cplex_d2gxdt(i) = 1 if d2gxdt(1,i,:,:) is real, 2 if it is pure imaginary
618 [ + + ]: 14154 : if(ndgxdt > 0) then
619 [ - + - - ]: 424 : if (choice==5.or.choice==51) cplex_dgxdt(:) = 2
620 [ - + - - : 424 : if (choice==54.and.signs==1) cplex_dgxdt(4:6) = 2
- - ]
621 : : !if (choice==54.and.signs==2) cplex_dgxdt(:) = 2
622 [ - + - - : 424 : if (choice==55.and.signs==1) cplex_dgxdt(7:9) = 2
- - ]
623 : : end if
624 [ - + ]: 14154 : if(nd2gxdt > 0) then
625 [ # # # # ]: 0 : if (choice==54) cplex_d2gxdt(:) = 2
626 [ # # # # : 0 : if (choice==55.and.signs==1) cplex_d2gxdt(1:18)= 2
# # ]
627 : : end if
628 : :
629 : : ! These will store the non-local factors for vectin, svectout and vectout respectively
630 [ + + ]: 14154 : if(.not. local_vectproj) then
631 [ - + + - : 65010 : ABI_MALLOC(projections,(cplex, nprojs,nspinor*ndat))
- + + - -
+ + - + -
+ - - + -
+ ]
632 : : #ifdef HAVE_OPENMP_OFFLOAD
633 : : !$OMP TARGET ENTER DATA MAP(alloc:projections) IF(gpu_option==ABI_GPU_OPENMP)
634 : : #endif
635 : : end if
636 [ - + + - : 70770 : ABI_MALLOC(s_projections,(cplex, nprojs,nspinor*ndat))
- + + - -
+ + - + -
+ - - + -
+ ]
637 [ - + + - : 70770 : ABI_MALLOC(vnl_projections,(cplex_fac, nprojs,nspinor*ndat))
- + + - -
+ + - + -
+ - - + -
+ ]
638 : : #ifdef HAVE_OPENMP_OFFLOAD
639 : : !$OMP TARGET ENTER DATA MAP(alloc:s_projections,vnl_projections) IF(gpu_option==ABI_GPU_OPENMP)
640 : : #endif
641 : :
642 [ + - ]: 14154 : if(gpu_option==ABI_GPU_DISABLED) then
643 [ + + + + : 8482993 : if(cpopt < 2) projections = zero
+ + + + ]
644 [ + + + + : 8694673 : s_projections = zero
+ + ]
645 [ + + + + : 8694673 : vnl_projections = zero
+ + ]
646 [ # # ]: 0 : else if(gpu_option==ABI_GPU_OPENMP) then
647 [ # # ]: 0 : if(cpopt < 2) call gpu_set_to_zero(projections, int(cplex,c_size_t)*nprojs*ndat*nspinor)
648 : 0 : call gpu_set_to_zero(s_projections, int(cplex,c_size_t)*nprojs*ndat*nspinor)
649 : 0 : call gpu_set_to_zero(vnl_projections, int(cplex_fac,c_size_t)*nprojs*ndat*nspinor)
650 : : end if
651 : :
652 : : ! Working buffers for storing derivative
653 [ + + ]: 14154 : if (ndgxdt>0) then
654 [ - + + - : 2120 : ABI_MALLOC(dprojections,(cplex, ndgxdt*nprojs,nspinor*ndat))
- + + - -
+ + - + -
+ - - + -
+ ]
655 : : #ifdef HAVE_OPENMP_OFFLOAD
656 : : !$OMP TARGET ENTER DATA MAP(alloc:dprojections) IF(gpu_option==ABI_GPU_OPENMP)
657 : : #endif
658 [ + - ]: 424 : if(cpopt < 4) then
659 [ + - ]: 424 : if(gpu_option==ABI_GPU_DISABLED) then
660 [ + + + + : 1464640 : dprojections(:,:,:) = zero
+ + ]
661 [ # # ]: 0 : else if(gpu_option==ABI_GPU_OPENMP) then
662 : 0 : call gpu_set_to_zero(dprojections, int(cplex,c_size_t)*ndgxdt*nprojs*ndat*nspinor)
663 : : end if
664 : : end if
665 : : else
666 [ - + + - : 41190 : ABI_MALLOC(dprojections,(1,1,ndat))
+ - + - -
+ - + ]
667 : : end if
668 : :
669 [ - + ]: 14154 : if (ndgxdtfac>0) then
670 [ # # # # : 0 : ABI_MALLOC(s_dprojections,(cplex, ndgxdtfac*nprojs,nspinor*ndat))
# # # # #
# # # # #
# # # # #
# ]
671 [ # # # # : 0 : ABI_MALLOC(vnl_dprojections,(cplex_fac, ndgxdtfac*nprojs,nspinor*ndat))
# # # # #
# # # # #
# # # # #
# ]
672 : : #ifdef HAVE_OPENMP_OFFLOAD
673 : : !$OMP TARGET ENTER DATA MAP(alloc:s_dprojections,vnl_dprojections) IF(gpu_option==ABI_GPU_OPENMP)
674 : : #endif
675 [ # # ]: 0 : if(gpu_option==ABI_GPU_DISABLED) then
676 [ # # # # : 0 : s_dprojections(:,:,:) = zero
# # ]
677 [ # # # # : 0 : vnl_dprojections(:,:,:) = zero
# # ]
678 [ # # ]: 0 : else if(gpu_option==ABI_GPU_OPENMP) then
679 : 0 : call gpu_set_to_zero(s_dprojections, int(cplex,c_size_t)*ndgxdtfac*nprojs*ndat*nspinor)
680 : 0 : call gpu_set_to_zero(vnl_dprojections, int(cplex_fac,c_size_t)*ndgxdtfac*nprojs*ndat*nspinor)
681 : : end if
682 : : else
683 [ - + + - : 42462 : ABI_MALLOC(s_dprojections,(1,1,ndat))
+ - + - -
+ - + ]
684 [ - + + - : 28308 : ABI_MALLOC(vnl_dprojections,(1,1,ndat))
- + - + ]
685 : : end if
686 : :
687 : : ! Working buffers for storing 2nd-derivative
688 [ - + ]: 14154 : if (nd2gxdt>0) then
689 [ # # # # : 0 : ABI_MALLOC(d2projections,(cplex, nd2gxdt*nprojs, nspinor*ndat))
# # # # #
# # # # #
# # # # #
# ]
690 : : #ifdef HAVE_OPENMP_OFFLOAD
691 : : !$OMP TARGET ENTER DATA MAP(alloc:d2projections) IF(gpu_option==ABI_GPU_OPENMP)
692 : : #endif
693 [ # # ]: 0 : if(cpopt < 4) then
694 [ # # ]: 0 : if(gpu_option==ABI_GPU_DISABLED) then
695 [ # # # # : 0 : d2projections(:,:,:) = zero
# # ]
696 [ # # ]: 0 : else if(gpu_option==ABI_GPU_OPENMP) then
697 : 0 : call gpu_set_to_zero(d2projections, int(cplex,c_size_t)*nd2gxdt*nprojs*ndat*nspinor)
698 : : end if
699 : : end if
700 : : else
701 [ - + + - : 42462 : ABI_MALLOC(d2projections,(1, 1, ndat))
+ - + - -
+ - + ]
702 : : end if
703 : :
704 : :
705 : : ! determine precisely when temp_realvec_r~i needs to be allocated
706 : : ! to factorize allocate (resp. deallocate) at the begining (resp. at the end) of subroutine
707 : : ! to avoid multiple allocate/deallocate that can be costly
708 [ + + ]: 14154 : if (cplex /= 2) then
709 : : if ( (cpopt < 2) .or. &
710 [ - + - - : 4111 : & (paw_opt == 3 .or. paw_opt == 4) .or. &
- - ]
711 : : & (paw_opt == 0 .or. paw_opt == 1 .or. paw_opt == 4)) then
712 [ - + + - : 12333 : ABI_MALLOC(temp_realvec_r,(MAX(npwout,npwin)*nspinor*ndat))
+ - + - -
+ - + -
+ ]
713 [ - + + - : 8222 : ABI_MALLOC(temp_realvec_i,(MAX(npwout,npwin)*nspinor*ndat))
- + - + -
+ ]
714 : : #ifdef HAVE_OPENMP_OFFLOAD
715 : : !$OMP TARGET ENTER DATA MAP(alloc:temp_realvec_r,temp_realvec_i) IF(gpu_option==ABI_GPU_OPENMP)
716 : : #endif
717 : : end if
718 : : end if
719 : :
720 [ + + ]: 14154 : if(cpopt >= 2) then
721 : : ! retrieve from cprjin
722 [ + + + - ]: 864 : if(.not. local_vectproj .and. cpopt/=3) then
723 : : !$OMP PARALLEL DO PRIVATE(shift,idat,iatom,nlmn)
724 [ + + ]: 2016 : do idat=1, ndat*nspinor
725 : : shift = 0
726 [ + + ]: 5472 : do iatom = ia_beg, ia_end
727 : 3456 : nlmn = cprjin(iatom, idat)%nlmn
728 [ + + + + ]: 86400 : projections(1:cplex, shift+1:shift+nlmn, idat) = cprjin(iatom, idat)%cp(1:cplex, 1:nlmn)
729 : 5184 : shift = shift + nlmn
730 : : end do
731 : : end do
732 : : #ifdef HAVE_OPENMP_OFFLOAD
733 : : !$OMP TARGET UPDATE TO(projections) IF(gpu_option==ABI_GPU_OPENMP)
734 : : #endif
735 : : end if
736 [ - + - - ]: 864 : if(cpopt==4.and.allocated(dprojections)) then
737 [ # # ]: 0 : ABI_CHECK(cprjin(1,1)%ncpgr>=ndgxdt,"cprjin%ncpgr not correct! (1)")
738 : 0 : ndgxdt_stored = cprjin(1,1)%ncpgr
739 : 0 : ishift=0
740 [ # # # # : 0 : if (((choice==2).or.(choice==3)).and.(ndgxdt_stored>ndgxdt).and.(signs==2)) ishift=idir-ndgxdt
# # ]
741 [ # # # # : 0 : if ((choice==2).and.(ndgxdt_stored==9).and.(signs==2)) ishift=ishift+6
# # ]
742 [ # # # # : 0 : if (choice==2.and.(ndgxdt_stored>ndgxdt).and.(signs==1)) ishift=ndgxdt_stored-ndgxdt
# # ]
743 : : !$OMP PARALLEL DO PRIVATE(shift,idat,iatom,igrad,nlmn)
744 [ # # ]: 0 : do idat=1, ndat*nspinor
745 : : shift = 0
746 [ # # ]: 0 : do iatom = ia_beg, ia_end
747 : 0 : nlmn = cprjin(iatom, idat)%nlmn
748 [ # # ]: 0 : do ilmn=1,nlmn
749 [ # # ]: 0 : do igrad=1,ndgxdt
750 : : dprojections(1:cplex, shift + igrad, idat) = &
751 [ # # ]: 0 : cprjin(iatom, idat)%dcp(1:cplex,igrad+ishift,ilmn)
752 : : end do
753 : 0 : shift = shift + ndgxdt
754 : : end do
755 : : end do
756 : : end do
757 : : #ifdef HAVE_OPENMP_OFFLOAD
758 : : !$OMP TARGET UPDATE TO(dprojections) IF(gpu_option==ABI_GPU_OPENMP)
759 : : #endif
760 : : end if
761 : : end if ! cpopt
762 : :
763 [ + + + - : 14154 : if(cpopt<=1.or.(cpopt<=3.and.(choice==2.or.choice==3.or.choice==5.or.choice==51.or.choice==23.or.choice==54.or.choice==55.or.choice==4))) then
- + ]
764 : :
765 : : call opernla_gemm(choice,cplex,cplex_dgxdt,cplex_d2gxdt,dimffnlin,&
766 : : & d2projections,dprojections,ffnlin,projections,&
767 : : & idir,indlmn,istwf_k,kpgin_,matblk,mpi_enreg,nd2gxdt,ndgxdt,nkpgin_,&
768 : : & npwin,nspinor,ph3din,signs,ucvol,ndat,ntypat,lmnmax,nattyp,(ikin==2),&
769 : : & iatom_only,atom_proj_shift,cpopt,&
770 : : & nprojs,&
771 : : & vectin,&
772 : : & temp_realvec_r,temp_realvec_i,&
773 : 13290 : & gpu_option,gemm_nonlop_is_distributed)
774 : :
775 [ + + ]: 13290 : if(cpopt >= 0) then
776 : : ! store in cprjin
777 [ + + + - ]: 2780 : if(.not. local_vectproj .and. cpopt/=3) then
778 : : #ifdef HAVE_OPENMP_OFFLOAD
779 : : !$OMP TARGET UPDATE FROM(projections) IF(gpu_option==ABI_GPU_OPENMP)
780 : : #endif
781 : : !$OMP PARALLEL DO PRIVATE(shift,idat,iatom,nlmn)
782 [ + + ]: 5492 : do idat=1, ndat*nspinor
783 : : shift = 0
784 [ + + ]: 12068 : do iatom = ia_beg, ia_end
785 : 6576 : nlmn = cprjin(iatom, idat)%nlmn
786 [ + + + + ]: 242656 : cprjin(iatom, idat)%cp(1:cplex, 1:nlmn) = projections(1:cplex, shift+1:shift+nlmn, idat)
787 : 9864 : shift = shift + nlmn
788 : : end do
789 : : end do
790 : : end if
791 [ - + ]: 2780 : if(cpopt==1 .or. cpopt==3) then
792 [ # # ]: 0 : ABI_CHECK(cprjin(1,1)%ncpgr>=ndgxdt,"cprjin%ncpgr not correct! (2)")
793 : : #ifdef HAVE_OPENMP_OFFLOAD
794 : : !$OMP TARGET UPDATE FROM(dprojections) IF(gpu_option==ABI_GPU_OPENMP)
795 : : #endif
796 : : !$OMP PARALLEL DO PRIVATE(shift,idat,iatom,igrad,nlmn)
797 [ # # ]: 0 : do idat=1, ndat*nspinor
798 : : shift = 0
799 [ # # ]: 0 : do iatom = ia_beg, ia_end
800 : 0 : nlmn = cprjin(iatom, idat)%nlmn
801 [ # # ]: 0 : do ilmn=1,nlmn
802 [ # # ]: 0 : do igrad=1,ndgxdt
803 : : cprjin(iatom, idat)%dcp(1:cplex,igrad,ilmn) = &
804 [ # # ]: 0 : & dprojections(1:cplex, shift + igrad, idat)
805 : : end do
806 : 0 : shift = shift + ndgxdt
807 : : end do
808 : : end do
809 : : end do
810 : : end if
811 : : end if ! cpopt >= 0
812 : : end if ! cpopt >= 2
813 : :
814 [ + + ]: 14154 : if(choice > 0) then
815 : :
816 [ + + ]: 11422 : if(choice /= 7) then
817 : : ! opernlc
818 : 10846 : iatm = 0
819 : 10846 : shift = 0; dshift = 0; dfshift = 0; d2shift = 0
820 [ + + ]: 29342 : do itypat=1, ntypat_
821 [ + + + + ]: 319464 : nlmn=count(indlmn_(3,:,itypat)>0)
822 : :
823 : 18496 : ibeg = shift+1
824 : 18496 : iend = shift+nattyp_(itypat)*nlmn
825 : :
826 : 18496 : idbeg = dshift+1
827 : 18496 : idend = dshift+nattyp_(itypat)*nlmn*ngrads
828 : :
829 : 18496 : idfbeg = dshift+1
830 : 18496 : idfend = dshift+nattyp_(itypat)*nlmn*ndgxdtfac
831 : :
832 : 18496 : id2beg = d2shift+1
833 : 18496 : id2end = d2shift+nattyp_(itypat)*nlmn*ngrads2
834 : :
835 : : call opernlc_ylm_allwf(atindx1_,cplex,cplex_dgxdt,cplex_d2gxdt,&
836 : : & cplex_enl,cplex_fac,&
837 : : & dprojections,&
838 : : & vnl_dprojections,&
839 : : & s_dprojections,&
840 : : & d2projections,d2gxdt_dum_out,d2gxdt_dum_out2,&
841 : : & dimenl1,dimenl2_,dimekbq,enl_,&
842 : : & projections,&
843 : : & vnl_projections,&
844 : : & s_projections,&
845 : : & iatm,indlmn_(:,:,itypat),itypat,lambda,mpi_enreg,natom_,&
846 : : & ndgxdt,ndgxdtfac,nd2gxdt,nd2gxdtfac,&
847 : : & nattyp_(itypat),nlmn,nspinor,nspinortot,optder,paw_opt,sij_typ(:,itypat),&
848 : 18496 : & ndat,ibeg-1,iend,nprojs,ndat_enl,gpu_option)
849 : :
850 : 18496 : shift = shift + nattyp_(itypat)*nlmn
851 : 18496 : dshift = dshift + nattyp_(itypat)*nlmn*ngrads
852 : 18496 : dfshift = dshift + nattyp_(itypat)*nlmn*ndgxdtfac
853 : 18496 : d2shift = d2shift + nattyp_(itypat)*nlmn*ngrads2
854 : 29342 : iatm = iatm+nattyp_(itypat)
855 : : end do
856 : : else
857 [ + - ]: 576 : if(gpu_option==ABI_GPU_DISABLED) then
858 [ + - + - : 128160 : s_projections = projections
+ - - + -
- + + + +
+ + ]
859 [ # # ]: 0 : else if(gpu_option==ABI_GPU_OPENMP) then
860 : 0 : call gpu_copy(s_projections, projections, int(cplex,c_size_t) * nprojs * nspinor * ndat)
861 : : end if
862 : : end if ! choice /= 7
863 : :
864 : : ! opernlb
865 [ + + ]: 11422 : if(signs==2) then
866 : :
867 : : call opernlb_gemm(choice,cplex,cplex_dgxdt,cplex_d2gxdt,cplex_fac,&
868 : : & d2gxdt_dum_in,d2gxdt_dum_out,&
869 : : & vnl_dprojections,s_dprojections,dimffnlout,ffnlout,&
870 : : & vnl_projections,s_projections,&
871 : : & idir,indlmn,kpgout_,matblk,istwf_k,&
872 : : & nd2gxdt,nd2gxdtfac,ndgxdt,ndgxdtfac,&
873 : : & nkpgout_,npwout,nspinor,signs,ucvol,ndat,&
874 : : & ntypat,lmnmax,nattyp,(ikout==2),iatom_only,atom_proj_shift,&
875 : : & paw_opt,ph3dout,&
876 : : & nprojs,&
877 : : & vectin_,vectout_,svectout_,&
878 : : & temp_realvec_r,temp_realvec_i,&
879 : 10902 : & gpu_option,gemm_nonlop_is_distributed)
880 : : end if
881 : :
882 : : ! opernld
883 [ + + ]: 11422 : if(signs==1) then
884 : 520 : nld_on_gpu = .false.
885 [ + - ]: 520 : if(choice==1 .or. choice==2 .or. choice==3 .or. choice==23 .or. choice==4 .or. choice==54 .or. choice==55 .or. choice==6) then
886 : 520 : if(gpu_option==ABI_GPU_OPENMP) nld_on_gpu = .true.
887 : : call opernld_ylm_allwf(choice,cplex,cplex_fac,ddkk,&
888 : : & dprojections,vnl_dprojections,s_dprojections,d2projections,&
889 : : & enlk,enlout,fnlk,projections,vnl_projections,s_projections,&
890 : : & natom,ndat,nd2gxdt,ndgxdt,&
891 : : & ndgxdtfac,indlmn_,ntypat_,lmnmax,nprojs,nnlout,nspinor,paw_opt,&
892 : 520 : & strnlk,nattyp_,gpu_option)
893 : : else
894 : 0 : shift=0; dshift=0; dfshift = 0; d2shift = 0; iatm=1
895 : : #ifdef HAVE_OPENMP_OFFLOAD
896 : : !$OMP TARGET UPDATE FROM(dprojections,vnl_dprojections,s_dprojections) IF(gpu_option==ABI_GPU_OPENMP)
897 : : !$OMP TARGET UPDATE FROM(d2projections) IF(gpu_option==ABI_GPU_OPENMP)
898 : : !$OMP TARGET UPDATE FROM(projections,vnl_projections,s_projections) IF(gpu_option==ABI_GPU_OPENMP)
899 : : #endif
900 [ # # ]: 0 : do itypat=1, ntypat_
901 [ # # # # ]: 0 : nlmn=count(indlmn_(3,:,itypat)>0)
902 : :
903 : 0 : ibeg = shift+1
904 : 0 : iend = shift+nattyp_(itypat)*nlmn
905 : :
906 : 0 : idbeg = dshift+1
907 : 0 : idend = dshift+nattyp_(itypat)*nlmn*ngrads
908 : :
909 : 0 : idfbeg = dshift+1
910 : 0 : idfend = dshift+nattyp_(itypat)*nlmn*ndgxdtfac
911 : :
912 : 0 : id2beg = d2shift+1
913 : 0 : id2end = d2shift+nattyp_(itypat)*nlmn*ngrads2
914 : :
915 [ # # ]: 0 : do idat=1,ndat
916 : : call opernld_ylm (choice,cplex,cplex_fac,ddkk(:,idat),&
917 : : & dprojections (:, idbeg:idend, 1+nspinor*(idat-1):nspinor*idat),&
918 : : & vnl_dprojections(:, idfbeg:idfend, 1+nspinor*(idat-1):nspinor*idat),&
919 : : & s_dprojections (:, idfbeg:idfend, 1+nspinor*(idat-1):nspinor*idat),&
920 : : & d2projections (:, id2beg:id2end, 1+nspinor*(idat-1):nspinor*idat),&
921 : : & enlk(idat),enlout(nnlout*(idat-1)+1:nnlout*idat),fnlk(:,idat),&
922 : : & projections (:, ibeg:iend, 1+nspinor*(idat-1):nspinor*idat),&
923 : : & vnl_projections(:, ibeg:iend, 1+nspinor*(idat-1):nspinor*idat),&
924 : : & s_projections (:, ibeg:iend, 1+nspinor*(idat-1):nspinor*idat),&
925 : : & iatm,natom_,1,nd2gxdt,ndgxdt,ndgxdtfac,&
926 [ # # # # : 0 : & nattyp_(itypat),nlmn,nnlout,nspinor,paw_opt,strnlk(:,idat))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
927 : : end do
928 : :
929 : 0 : shift = shift + nattyp_(itypat)*nlmn
930 : 0 : dshift = dshift + nattyp_(itypat)*nlmn*ngrads
931 : 0 : dfshift = dshift + nattyp_(itypat)*nlmn*ndgxdtfac
932 : 0 : d2shift = d2shift + nattyp_(itypat)*nlmn*ngrads2
933 : 0 : iatm = iatm+nattyp_(itypat)
934 : : end do
935 : : end if
936 : :
937 : : #ifdef HAVE_OPENMP_OFFLOAD
938 : : !$OMP TARGET UPDATE FROM(enlout) if(nld_on_gpu)
939 : : #endif
940 : :
941 : : ! Reduction in case of parallelism
942 [ - + ]: 520 : if (mpi_enreg%paral_spinor==1) then
943 [ # # ]: 0 : if (size(enlout)>0) then
944 : 0 : call xmpi_sum(enlout,mpi_enreg%comm_spinor,ierr)
945 : : end if
946 [ # # ]: 0 : if (choice==3.or.choice==23) then
947 : : #ifdef HAVE_OPENMP_OFFLOAD
948 : : !$OMP TARGET UPDATE FROM(enlk) if(nld_on_gpu)
949 : : #endif
950 : 0 : call xmpi_sum(enlk,mpi_enreg%comm_spinor,ierr)
951 : : end if
952 [ # # ]: 0 : if (choice==55) then
953 : 0 : call xmpi_sum(ddkk,mpi_enreg%comm_spinor,ierr)
954 : : end if
955 : : end if
956 : :
957 : : !Need sometimes gmet
958 [ + - + - : 520 : if ((signs==1.and.paw_opt<=3).and. &
+ - + - +
- + - ]
959 : : & (choice==5 .or.choice==51.or.choice==52.or.choice==53.or.&
960 : : & choice==54.or.choice==55)) then
961 [ # # ]: 0 : ABI_MALLOC(gmet2,(3,3))
962 [ - - - - : 520 : gmet2 = MATMUL(TRANSPOSE(gprimd),gprimd)
- - - - -
- - - - -
- - ]
963 : : end if
964 : :
965 : : !Coordinate transformations
966 : :
967 : : ! Derivatives wrt strain
968 : : ! - Convert from reduced to cartesian coordinates
969 : : ! - Substract volume contribution
970 [ + + + - ]: 520 : if ((choice==3.or.choice==23).and.paw_opt<=3) then
971 : : #ifdef HAVE_OPENMP_OFFLOAD
972 : : !$OMP TARGET UPDATE FROM(enlk) if(nld_on_gpu)
973 : : #endif
974 [ + + ]: 980 : do idat=1,ndat
975 : 768 : enlout_shift=(idat-1)*nnlout
976 : 768 : call strconv(enlout(enlout_shift+1:enlout_shift+6),gprimd,work)
977 [ + + ]: 3072 : enlout(enlout_shift+1:enlout_shift+3)=(work(1:3)-enlk(idat))
978 [ + + ]: 3284 : enlout(enlout_shift+4:enlout_shift+6)= work(4:6)
979 : : end do
980 : : end if
981 : :
982 : : !2nd derivative wrt to k wave vector and atomic position (effective charges):
983 : : ! - convert from cartesian to reduced coordinates
984 [ - + - - ]: 520 : if (choice==54.and.signs==1.and.paw_opt<=3) then
985 [ # # ]: 0 : ABI_MALLOC(work1,(3))
986 [ # # ]: 0 : ABI_MALLOC(work2,(3))
987 [ # # ]: 0 : do idat=1,ndat
988 : 0 : mu0=0 ! Shift to be applied in enlout array
989 : 0 : enlout_shift=(idat-1)*nnlout
990 [ # # ]: 0 : do mu=1,3*natom
991 : : ! First, real part
992 : 0 : work1(1)=enlout(enlout_shift+mu0+1);work1(2)=enlout(enlout_shift+mu0+3);work1(3)=enlout(enlout_shift+mu0+5)
993 [ # # ]: 0 : work2(:)=gmet2(:,1)*work1(1)+gmet2(:,2)*work1(2)+gmet2(:,3)*work1(3)
994 : 0 : enlout(enlout_shift+mu0+1)=work2(1);enlout(enlout_shift+mu0+3)=work2(2);enlout(enlout_shift+mu0+5)=work2(3)
995 : : ! Then imaginary part
996 : 0 : work1(1)=enlout(enlout_shift+mu0+2);work1(2)=enlout(enlout_shift+mu0+4);work1(3)=enlout(enlout_shift+mu0+6)
997 [ # # ]: 0 : work2(:)=gmet2(:,1)*work1(1)+gmet2(:,2)*work1(2)+gmet2(:,3)*work1(3)
998 : 0 : enlout(enlout_shift+mu0+2)=work2(1);enlout(enlout_shift+mu0+4)=work2(2);enlout(enlout_shift+mu0+6)=work2(3)
999 : 0 : mu0=mu0+6
1000 : : end do
1001 : : end do !idat
1002 [ # # ]: 0 : ABI_FREE(work1)
1003 [ # # ]: 0 : ABI_FREE(work2)
1004 : : end if
1005 : :
1006 : : !2nd derivative wrt to k wave vector and strain (piezoelectric tensor):
1007 : : ! - convert from cartesian to reduced coordinates (k point)
1008 : : ! - convert from reduced to cartesian coordinates (strain)
1009 : : ! - substract volume contribution
1010 : : ! - symetrize strain components
1011 [ - + - - : 520 : if (choice==55.and.signs==1.and.paw_opt<=3) then
- - ]
1012 : : #ifdef HAVE_OPENMP_OFFLOAD
1013 : : !$OMP TARGET UPDATE FROM(ddkk) if(nld_on_gpu)
1014 : : #endif
1015 [ # # ]: 0 : ABI_MALLOC(work3,(2,3))
1016 [ # # ]: 0 : ABI_MALLOC(work4,(2,3))
1017 [ # # ]: 0 : ABI_MALLOC(work5,(2,3,6))
1018 [ # # ]: 0 : ABI_MALLOC(work7,(2,3,6))
1019 [ # # ]: 0 : ABI_MALLOC(work6,(2,3,3))
1020 [ # # ]: 0 : do idat=1,ndat
1021 : 0 : enlout_shift=(idat-1)*nnlout
1022 [ # # ]: 0 : do ic=1,3 ! gamma
1023 [ # # # # : 0 : work5=zero
# # ]
1024 [ # # ]: 0 : do jc=1,3 ! nu
1025 [ # # ]: 0 : do ii=1,3 ! lambda
1026 : 0 : mu=(gamma(jc,ii)-1)*3+1
1027 : : work5(1,jc,ii)=gmet2(ic,1)*enlout(enlout_shift+2*mu-1)+gmet2(ic,2)*enlout(enlout_shift+2*mu+1) &
1028 : 0 : & +gmet2(ic,3)*enlout(enlout_shift+2*mu+3)
1029 : : work5(2,jc,ii)=gmet2(ic,1)*enlout(enlout_shift+2*mu )+gmet2(ic,2)*enlout(enlout_shift+2*mu+2) &
1030 : 0 : & +gmet2(ic,3)*enlout(enlout_shift+2*mu+4)
1031 : : end do
1032 : : end do
1033 [ # # # # : 0 : work6=zero
# # ]
1034 [ # # ]: 0 : do jc=1,3 ! nu
1035 [ # # ]: 0 : do ii=1,3 ! beta
1036 : : work6(1:cplex,ii,jc)=gprimd(ii,1)*work5(1:cplex,jc,1)+gprimd(ii,2)*work5(1:cplex,jc,2) &
1037 [ # # ]: 0 : & +gprimd(ii,3)*work5(1:cplex,jc,3)
1038 : : end do
1039 : : end do
1040 [ # # ]: 0 : do jc=1,3 ! alpha
1041 [ # # ]: 0 : do ii=1,3 ! beta
1042 : 0 : mu=gamma(jc,ii)
1043 : : work7(1:cplex,ic,mu)=gprimd(jc,1)*work6(1:cplex,ii,1)+gprimd(jc,2)*work6(1:cplex,ii,2) &
1044 [ # # ]: 0 : & +gprimd(jc,3)*work6(1:cplex,ii,3)
1045 : : end do
1046 : : end do
1047 : : end do ! gamma
1048 : :
1049 [ # # ]: 0 : do ii=1,3 ! alpha
1050 : : work3(1,ii)=gprimd(ii,1)*ddkk(2*1-1,idat)+gprimd(ii,2)*ddkk(2*2-1,idat) &
1051 : 0 : & +gprimd(ii,3)*ddkk(2*3-1,idat)
1052 : : work3(2,ii)=gprimd(ii,1)*ddkk(2*1 ,idat)+gprimd(ii,2)*ddkk(2*2 ,idat) &
1053 : 0 : & +gprimd(ii,3)*ddkk(2*3 ,idat)
1054 : : end do
1055 [ # # ]: 0 : do ii=1,3 ! gamma
1056 : : work4(1,ii)=gmet2(ii,1)*ddkk(2*1-1,idat)+gmet2(ii,2)*ddkk(2*2-1,idat) &
1057 : 0 : & +gmet2(ii,3)*ddkk(2*3-1,idat)
1058 : : work4(2,ii)=gmet2(ii,1)*ddkk(2*1 ,idat)+gmet2(ii,2)*ddkk(2*2 ,idat) &
1059 : 0 : & +gmet2(ii,3)*ddkk(2*3 ,idat)
1060 : : end do
1061 : :
1062 [ # # ]: 0 : do mu=1,6
1063 : 0 : ii=alpha(mu) ! alpha
1064 : 0 : ic=beta(mu) ! beta
1065 [ # # ]: 0 : do jc=1,3 ! gamma
1066 : : work7(1:cplex,jc,mu)=work7(1:cplex,jc,mu)-half &
1067 [ # # ]: 0 : & *(gprimd(ic,jc)*work3(1:cplex,ii)+gprimd(ii,jc)*work3(1:cplex,ic))
1068 [ # # # # ]: 0 : if (ii==ic) work7(1:cplex,jc,mu)=work7(1:cplex,jc,mu)-work4(1:cplex,jc)
1069 : : end do
1070 : : end do
1071 [ # # ]: 0 : do mu=1,6 ! alpha,beta
1072 [ # # ]: 0 : do nu=1,3 ! gamma
1073 : 0 : mu0=3*(mu-1)+nu
1074 : 0 : enlout(enlout_shift+2*mu0-1)=work7(1,nu,mu)
1075 : 0 : enlout(enlout_shift+2*mu0 )=work7(2,nu,mu)
1076 : : end do
1077 : : end do
1078 : : end do !idat
1079 [ # # ]: 0 : ABI_FREE(work3)
1080 [ # # ]: 0 : ABI_FREE(work4)
1081 [ # # ]: 0 : ABI_FREE(work5)
1082 [ # # ]: 0 : ABI_FREE(work6)
1083 [ # # ]: 0 : ABI_FREE(work7)
1084 : : end if
1085 : :
1086 : :
1087 : : !2nd derivative wrt to 2 strains (elastic tensor):
1088 : : ! - convert from reduced to cartesian coordinates
1089 : : ! - substract volume contribution
1090 [ - + - - : 520 : if (choice==6.and.signs==1.and.paw_opt<=3) then
- - ]
1091 : : #ifdef HAVE_OPENMP_OFFLOAD
1092 : : !$OMP TARGET UPDATE FROM(enlk,strnlk,fnlk) if(nld_on_gpu)
1093 : : #endif
1094 [ # # ]: 0 : ABI_MALLOC(work1,(6))
1095 [ # # ]: 0 : ABI_MALLOC(work2,(6))
1096 [ # # # # : 0 : ABI_MALLOC(work3,(6+3*natom,6))
# # # # #
# # # # #
# # ]
1097 [ # # ]: 0 : do idat=1,ndat
1098 : 0 : mu0=(idat-1)*nnlout ! Shift to be applied in enlout array
1099 [ # # ]: 0 : work3(:,:)=reshape(enlout(mu0+1:mu0+6*(6+3*natom)),(/6+3*natom,6/))
1100 [ # # ]: 0 : do mu=1,6
1101 : 0 : call strconv(work3(1:6,mu),gprimd,work3(1:6,mu))
1102 : : end do
1103 [ # # ]: 0 : do mu=1,6+3*natom
1104 [ # # ]: 0 : work1(1:6)=work3(mu,1:6)
1105 : 0 : call strconv(work1,gprimd,work2)
1106 [ # # ]: 0 : work3(mu,1:6)=work2(1:6)
1107 : : end do
1108 [ # # ]: 0 : enlout(mu0+1:mu0+6*(6+3*natom))=reshape(work3(:,:),(/6*(6+3*natom)/))
1109 : 0 : call strconv(strnlk(:,idat),gprimd,strnlk(:,idat))
1110 [ # # ]: 0 : do mub=1,6
1111 : 0 : nub1=alpha(mub);nub2=beta(mub)
1112 [ # # ]: 0 : do mua=1,6
1113 : 0 : mu=mu0+mua+(3*natom+6)*(mub-1)
1114 : 0 : nua1=alpha(mua);nua2=beta(mua)
1115 [ # # ]: 0 : if (mua<=3.and.mub<=3) enlout(mu)=enlout(mu)+enlk(idat)
1116 [ # # ]: 0 : if (mua<=3) enlout(mu)=enlout(mu)-strnlk(mub,idat)
1117 [ # # ]: 0 : if (mub<=3) enlout(mu)=enlout(mu)-strnlk(mua,idat)
1118 [ # # ]: 0 : if (nub1==nua2) enlout(mu)=enlout(mu)-0.25d0*strnlk(gamma(nua1,nub2),idat)
1119 [ # # ]: 0 : if (nub2==nua2) enlout(mu)=enlout(mu)-0.25d0*strnlk(gamma(nua1,nub1),idat)
1120 [ # # ]: 0 : if (nub1==nua1) enlout(mu)=enlout(mu)-0.25d0*strnlk(gamma(nua2,nub2),idat)
1121 [ # # ]: 0 : if (nub2==nua1) enlout(mu)=enlout(mu)-0.25d0*strnlk(gamma(nua2,nub1),idat)
1122 : : end do
1123 [ # # ]: 0 : if (mub<=3) then
1124 [ # # ]: 0 : do nua1=1,natom
1125 : 0 : nua2=3*(nua1-1);mu=mu0+nua2+6+(3*natom+6)*(mub-1)
1126 [ # # ]: 0 : enlout(mu+1:mu+3)=enlout(mu+1:mu+3)-fnlk(nua2+1:nua2+3,idat)
1127 : : end do
1128 : : end if
1129 : : end do
1130 : : end do
1131 [ # # ]: 0 : ABI_FREE(work1)
1132 [ # # ]: 0 : ABI_FREE(work2)
1133 [ # # ]: 0 : ABI_FREE(work3)
1134 : : end if
1135 : :
1136 : : end if !opernld
1137 : :
1138 : : end if ! choice>0
1139 : :
1140 : : #ifdef HAVE_OPENMP_OFFLOAD
1141 : : if(gpu_option==ABI_GPU_OPENMP) then
1142 : : ! Retrieve and release allocated buffers
1143 : : !$OMP TARGET EXIT DATA MAP(delete:vectin) IF(transfer_vectin)
1144 : : !$OMP TARGET EXIT DATA MAP(from:vectout) IF(transfer_vectout)
1145 : : !$OMP TARGET EXIT DATA MAP(from:svectout) IF(transfer_svectout)
1146 : :
1147 : : !$OMP TARGET EXIT DATA MAP(delete:s_projections,vnl_projections)
1148 : : !$OMP TARGET EXIT DATA MAP(delete:projections) IF(.not. local_vectproj)
1149 : : !$OMP TARGET EXIT DATA MAP(delete:dprojections) IF(ndgxdt>0)
1150 : : !$OMP TARGET EXIT DATA MAP(delete:s_dprojections) IF(ndgxdtfac>0)
1151 : : !$OMP TARGET EXIT DATA MAP(delete:vnl_dprojections) IF(ndgxdtfac>0)
1152 : : !$OMP TARGET EXIT DATA MAP(delete:d2projections) IF(nd2gxdt>0)
1153 : :
1154 : : if (cplex /= 2) then
1155 : : if ( (cpopt < 2) .or. &
1156 : : & (paw_opt == 3 .or. paw_opt == 4) .or. &
1157 : : & (paw_opt == 0 .or. paw_opt == 1 .or. paw_opt == 4)) then
1158 : : !$OMP TARGET EXIT DATA MAP(delete:temp_realvec_r,temp_realvec_i)
1159 : : end if
1160 : : end if
1161 : :
1162 : : if(size(enl_)>0) then
1163 : : !$OMP TARGET EXIT DATA MAP(delete:enl_)
1164 : : end if
1165 : :
1166 : : if(paw_opt>=2 .and. choice > 0 .and. choice /= 7) then
1167 : : !$OMP TARGET EXIT DATA MAP(delete:sij_typ) IF(gpu_option==ABI_GPU_OPENMP)
1168 : : end if
1169 : :
1170 : : !$OMP TARGET EXIT DATA MAP(delete:kpgin_) IF(nkpgin_ > 0)
1171 : : !$OMP TARGET EXIT DATA MAP(delete:kpgout_) IF(nkpgout_ > 0)
1172 : :
1173 : : !$OMP TARGET EXIT DATA MAP(delete:enlk,fnlk,strnlk,ddkk,enlout) IF(signs == 1 .and. choice > 0)
1174 : : !$OMP TARGET EXIT DATA MAP(delete:atindx1,indlmn)
1175 : : end if
1176 : : #endif
1177 : :
1178 : : ! Release memory
1179 : :
1180 [ - + ]: 14154 : if (iatom_only>0) then
1181 [ # # ]: 0 : ABI_FREE(atindx1_)
1182 [ # # ]: 0 : ABI_FREE(nattyp_)
1183 [ # # ]: 0 : ABI_FREE(ph3din_)
1184 [ # # ]: 0 : ABI_FREE(ph3dout_)
1185 [ # # ]: 0 : ABI_FREE(ffnlin_)
1186 [ # # ]: 0 : ABI_FREE(ffnlout_)
1187 [ # # ]: 0 : ABI_FREE(enl_)
1188 [ # # ]: 0 : ABI_FREE(indlmn_)
1189 [ # # # # ]: 0 : if (size(sij) > 1) then
1190 [ # # ]: 0 : ABI_FREE(sij_)
1191 : : end if
1192 : : end if
1193 : :
1194 [ + + + + ]: 14154 : if(signs == 1 .and. choice > 0) then
1195 : : #ifdef HAVE_OPENMP_OFFLOAD
1196 : : #endif
1197 [ - + ]: 520 : ABI_FREE(enlk)
1198 [ - + ]: 520 : ABI_FREE(fnlk)
1199 [ - + ]: 520 : ABI_FREE(strnlk)
1200 [ - + ]: 520 : ABI_FREE(ddkk)
1201 : : end if
1202 : :
1203 [ + + ]: 14154 : if (nkpgin<nkpgin_) then
1204 [ - + ]: 64 : ABI_FREE(kpgin_)
1205 : : end if
1206 [ - + ]: 14154 : if (nkpgout<nkpgout_) then
1207 [ # # ]: 0 : ABI_FREE(kpgout_)
1208 : : end if
1209 : :
1210 [ - + ]: 14154 : if (allocated(gmet2)) then
1211 : 0 : ABI_FREE(gmet2)
1212 : : end if
1213 : :
1214 [ + - ]: 14154 : if (allocated(sij_typ)) then
1215 : 14154 : ABI_FREE(sij_typ)
1216 : : end if
1217 : :
1218 [ - + ]: 14154 : ABI_FREE(cplex_dgxdt)
1219 [ - + ]: 14154 : ABI_FREE(cplex_d2gxdt)
1220 : :
1221 [ + + ]: 14154 : if(.not. local_vectproj) then
1222 [ - + ]: 13002 : ABI_FREE(projections)
1223 : : end if
1224 [ - + ]: 14154 : ABI_FREE(s_projections)
1225 [ - + ]: 14154 : ABI_FREE(vnl_projections)
1226 [ + - ]: 14154 : if (allocated(dprojections)) then
1227 : 14154 : ABI_FREE(dprojections)
1228 : : end if
1229 [ + - ]: 14154 : if (allocated(s_dprojections)) then
1230 : 14154 : ABI_FREE(s_dprojections)
1231 : : end if
1232 [ + - ]: 14154 : if (allocated(vnl_dprojections)) then
1233 : 14154 : ABI_FREE(vnl_dprojections)
1234 : : end if
1235 [ + - ]: 14154 : if (allocated(d2projections)) then
1236 : 14154 : ABI_FREE(d2projections)
1237 : : end if
1238 [ + + ]: 14154 : if (allocated(temp_realvec_r)) then
1239 : 4111 : ABI_FREE(temp_realvec_r)
1240 [ - + ]: 4111 : ABI_FREE(temp_realvec_i)
1241 : : end if
1242 : :
1243 [ - + - + : 28308 : end subroutine gemm_nonlop
- + - + -
+ - + -
+ ]
1244 : : !***
1245 : :
1246 : : end module m_gemm_nonlop
1247 : : !!***
|