Branch data Line data Source code
1 : : !!****m* ABINIT/m_FFT_prof
2 : : !! NAME
3 : : !! m_FFT_prof
4 : : !!
5 : : !! COPYRIGHT
6 : : !! Copyright (C) 2008-2026 ABINIT group (MG)
7 : : !! This file is distributed under the terms of the
8 : : !! GNU General Public License, see ~abinit/COPYING
9 : : !! or http://www.gnu.org/copyleft/gpl.txt .
10 : : !!
11 : : !! SOURCE
12 : :
13 : : #if defined HAVE_CONFIG_H
14 : : #include "config.h"
15 : : #endif
16 : :
17 : : #include "abi_common.h"
18 : :
19 : : module m_FFT_prof
20 : :
21 : : use defs_basis
22 : : use m_xomp
23 : : use m_errors
24 : : use m_abicore
25 : : use m_fftw3
26 : : use m_fft
27 : : use m_distribfft
28 : :
29 : : use defs_abitypes, only : MPI_type
30 : : use m_fstrings, only : sjoin, itoa
31 : : use m_numeric_tools, only : arth
32 : : use m_time, only : cwtime
33 : : use m_io_tools, only : open_file
34 : : use m_geometry, only : metric
35 : : use m_hide_blas, only : xcopy
36 : : use m_cgtools, only : set_istwfk
37 : : use m_fftcore, only : get_kg, print_ngfft, fftalg_info, kgindex, getng, sphereboundary
38 : : use m_fft_mesh, only : calc_eigr, calc_ceigr
39 : : use m_mpinfo, only : nullify_mpi_enreg, destroy_mpi_enreg, copy_mpi_enreg, initmpi_seq
40 : : use m_oscillators, only : rho_tw_g
41 : :
42 : : implicit none
43 : :
44 : : private
45 : :
46 : : integer,private,parameter :: TNAME_LEN=100
47 : : !!***
48 : :
49 : : !----------------------------------------------------------------------
50 : :
51 : : public :: fftprof_ncalls_per_test
52 : :
53 : : ! Routines for benchmarking
54 : : public :: prof_fourdp
55 : : public :: prof_fourwf
56 : : public :: prof_rhotwg
57 : :
58 : : !----------------------------------------------------------------------
59 : :
60 : : !!****t* m_fft_mesh/FFT_test_t
61 : : !! NAME
62 : : !! FFT_test_t
63 : : !!
64 : : !! FUNCTION
65 : : !! Parameters passed to the FFT routines used in abinit (fourdp|fourwf).
66 : : !!
67 : : !! SOURCE
68 : :
69 : : type, public :: FFT_test_t
70 : :
71 : : integer :: available = 0
72 : : integer :: istwf_k = -1
73 : : integer :: mgfft = -1
74 : : integer :: ndat = -1
75 : : integer :: nfft = -1
76 : : integer :: nthreads = 1
77 : : integer :: npw_k = -1
78 : : integer :: npw_kout = -1
79 : : integer :: paral_kgb = -1
80 : : integer :: gpu_option = 0
81 : :
82 : : real(dp) :: ecut=zero
83 : : integer :: ngfft(18)=-1
84 : :
85 : : real(dp) :: kpoint(3) = [zero,zero,zero]
86 : : real(dp) :: rprimd(3,3),rmet(3,3)
87 : : real(dp) :: gprimd(3,3),gmet(3,3)
88 : :
89 : : integer,allocatable :: kg_k(:,:)
90 : : integer,allocatable :: kg_kout(:,:)
91 : : integer,allocatable :: indpw_k(:)
92 : :
93 : : type(MPI_type) :: MPI_enreg
94 : :
95 : : contains
96 : : procedure :: init => fft_test_init
97 : : procedure :: free => fft_test_free_0D
98 : : procedure :: print => fft_test_print
99 : : procedure :: get_name
100 : :
101 : : ! Timing routines.
102 : : procedure :: time_fourdp
103 : : procedure :: time_fftbox
104 : : procedure :: time_fourwf
105 : : procedure :: time_rhotwg
106 : : procedure :: time_fftu
107 : : end type FFT_test_t
108 : :
109 : : public :: fft_tests_free
110 : :
111 : : interface fft_tests_free
112 : : module procedure fft_test_free_0D
113 : : module procedure fft_test_free_1D
114 : : end interface fft_tests_free
115 : : !!***
116 : :
117 : : !----------------------------------------------------------------------
118 : :
119 : : !!****t* m_fft_mesh/FFT_prof_t
120 : : !! NAME
121 : : !! FFT_prof_t
122 : : !!
123 : : !! FUNCTION
124 : : !! The results of the tests
125 : : !!
126 : : !! SOURCE
127 : :
128 : : type,public :: FFT_prof_t
129 : : integer :: ncalls
130 : : integer :: ndat
131 : : integer :: gpu_option
132 : : integer :: nthreads
133 : : real(dp) :: cpu_time
134 : : real(dp) :: wall_time
135 : : real(dp) :: gflops
136 : : character(len=TNAME_LEN) :: test_name
137 : : complex(dp),allocatable :: results(:)
138 : :
139 : : contains
140 : : procedure :: init => fftprof_init
141 : : procedure :: free => fftprof_free_0D
142 : : end type FFT_prof_t
143 : :
144 : : public :: fftprofs_free
145 : : public :: fftprofs_print
146 : :
147 : : interface fftprofs_free
148 : : module procedure fftprof_free_0D
149 : : module procedure fftprof_free_1D
150 : : end interface fftprofs_free
151 : : !!***
152 : :
153 : : !----------------------------------------------------------------------
154 : : ! Number of calls of each FFT algo, used to have a betters statistics for timing.
155 : : integer,save,private :: NCALLS_FOR_TEST=10
156 : :
157 : : integer,private,parameter :: CACHE_KBSIZE=0
158 : : ! Argument of empty_cache. Set it to zero if the cache should not be emptied.
159 : :
160 : : CONTAINS !====================================================================
161 : : !!***
162 : :
163 : : !----------------------------------------------------------------------
164 : :
165 : : !!****f* m_FFT_prof/fft_test_init
166 : : !! NAME
167 : : !! fft_test_init
168 : : !!
169 : : !! FUNCTION
170 : : !! Creation method for the FFT_test_t structured datatype.
171 : : !!
172 : : !! INPUTS
173 : : !!
174 : : !! OUTPUT
175 : : !!
176 : : !! SOURCE
177 : :
178 : 98 : subroutine fft_test_init(Ftest, fft_setup, kpoint, ecut, boxcutmin, rprimd, nsym, symrel, MPI_enreg_in)
179 : :
180 : : !Arguments -----------------------------------
181 : : !scalars
182 : : class(FFT_test_t),intent(inout) :: Ftest
183 : : integer,intent(in) :: nsym
184 : : real(dp),intent(in) :: ecut,boxcutmin
185 : : class(MPI_type),intent(in) :: MPI_enreg_in
186 : : !arrays
187 : : integer,intent(in) :: fft_setup(6),symrel(3,3,nsym)
188 : : real(dp),intent(in) :: kpoint(3),rprimd(3,3)
189 : :
190 : : !Local variables-------------------------------
191 : : !scalars
192 : : integer :: fftalg,fftcache,ndat
193 : : real(dp) :: ucvol
194 : : !arrays
195 : 98 : logical,allocatable :: mask(:)
196 : : real(dp),parameter :: k0(3)=zero
197 : : real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3)
198 : 98 : real(dp),allocatable :: tnons(:,:)
199 : : ! *************************************************************************
200 : :
201 : 98 : call nullify_mpi_enreg(Ftest%MPI_enreg)
202 : :
203 : 98 : call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
204 : :
205 [ + + + + ]: 1274 : Ftest%rprimd = rprimd
206 [ + + + + ]: 1274 : Ftest%rmet = rmet
207 [ + + + + ]: 1274 : Ftest%gprimd = gprimd
208 [ + + + + ]: 1274 : Ftest%gmet = gmet
209 : 98 : Ftest%ecut = ecut
210 : :
211 : 98 : fftalg = fft_setup(1)
212 : 98 : fftcache = fft_setup(2)
213 : 98 : ndat = fft_setup(3)
214 : 98 : Ftest%nthreads = fft_setup(4)
215 : 98 : Ftest%available = fft_setup(5)
216 : 98 : Ftest%gpu_option = fft_setup(6)
217 : :
218 : 98 : Ftest%paral_kgb = 0
219 [ + + ]: 392 : Ftest%kpoint = kpoint
220 : 98 : Ftest%ndat = ndat
221 : :
222 : 98 : Ftest%istwf_k = set_istwfk(kpoint)
223 : :
224 [ - + ]: 98 : call get_kg(Ftest%kpoint,Ftest%istwf_k,ecut,gmet,Ftest%npw_k,Ftest%kg_k)
225 [ - + ]: 98 : call get_kg(Ftest%kpoint,Ftest%istwf_k,ecut,gmet,Ftest%npw_kout,Ftest%kg_kout)
226 : :
227 : 98 : call copy_mpi_enreg(MPI_enreg_in,Ftest%MPI_enreg)
228 : :
229 : 98 : Ftest%ngfft(7) = fftalg
230 : 98 : Ftest%ngfft(8) = fftcache
231 : :
232 : : ! Fill part of ngfft
233 [ - + + - : 686 : ABI_CALLOC(tnons,(3,nsym))
+ - + - -
+ - + + +
+ + ]
234 : :
235 : : call getng(boxcutmin,0,ecut,gmet,k0,Ftest%MPI_enreg%me_fft,Ftest%mgfft,Ftest%nfft,Ftest%ngfft,Ftest%MPI_enreg%nproc_fft,nsym,&
236 : 98 : Ftest%MPI_enreg%paral_kgb,symrel,tnons, unit=dev_null, gpu_option=ftest%gpu_option)
237 : :
238 [ - + ]: 98 : ABI_FREE(tnons)
239 : :
240 : 98 : call Ftest%MPI_enreg%distribfft%init('c',Ftest%MPI_enreg%nproc_fft,Ftest%ngfft(2),Ftest%ngfft(3))
241 : :
242 : : ! Compute the index of each plane wave in the FFT grid.
243 [ - + + - : 294 : ABI_MALLOC(Ftest%indpw_k,(Ftest%npw_k))
+ - + - -
+ - + -
+ ]
244 : :
245 [ - + + - : 196 : ABI_MALLOC(mask,(Ftest%npw_k))
- + - + ]
246 : 98 : call kgindex(Ftest%indpw_k,Ftest%kg_k,mask,Ftest%MPI_enreg,Ftest%ngfft,Ftest%npw_k)
247 [ + + + - : 2474319 : ABI_CHECK(ALL(mask),"FFT parallelism not supported in fftprof")
- + ]
248 [ - + ]: 98 : ABI_FREE(mask)
249 : :
250 : 98 : end subroutine fft_test_init
251 : : !!***
252 : :
253 : : !----------------------------------------------------------------------
254 : :
255 : : !!****f* m_FFT_prof/fft_test_free_0D
256 : : !! NAME
257 : : !! fft_test_free_0D
258 : : !!
259 : : !! FUNCTION
260 : : !! Destruction method for the FFT_test_t structured datatype.
261 : : !!
262 : : !! INPUTS
263 : : !!
264 : : !! OUTPUT
265 : : !!
266 : : !! SOURCE
267 : :
268 : 98 : subroutine fft_test_free_0D(Ftest)
269 : :
270 : : !Arguments -----------------------------------
271 : : class(FFT_test_t),intent(inout) :: Ftest
272 : : ! *********************************************************************
273 : :
274 [ + - ]: 98 : ABI_SFREE(Ftest%indpw_k)
275 [ + - ]: 98 : ABI_SFREE(Ftest%kg_k)
276 [ + - ]: 98 : ABI_SFREE(Ftest%kg_kout)
277 : :
278 : 98 : call destroy_mpi_enreg(Ftest%MPI_enreg)
279 : :
280 : 98 : end subroutine fft_test_free_0D
281 : : !!***
282 : :
283 : : !----------------------------------------------------------------------
284 : :
285 : : !!****f* m_FFT_prof/fft_test_free_1D
286 : : !! NAME
287 : : !! fft_test_free_1D
288 : : !!
289 : : !! FUNCTION
290 : : !! Destruction method for the FFT_test_t structured datatype.
291 : : !!
292 : : !! INPUTS
293 : : !!
294 : : !! OUTPUT
295 : : !!
296 : : !! SOURCE
297 : :
298 : 17 : subroutine fft_test_free_1D(Ftest)
299 : :
300 : : !Arguments -----------------------------------
301 : : class(FFT_test_t),intent(inout) :: Ftest(:)
302 : :
303 : : !Local variables-------------------------------
304 : : integer :: ii
305 : : ! *********************************************************************
306 : :
307 [ + - + + ]: 132 : do ii=LBOUND(Ftest,DIM=1),UBOUND(Ftest,DIM=1)
308 : 115 : call Ftest(ii)%free()
309 : : end do
310 : :
311 : 17 : end subroutine fft_test_free_1D
312 : : !!***
313 : :
314 : : !----------------------------------------------------------------------
315 : :
316 : : !!****f* m_FFT_prof/fft_test_print
317 : : !! NAME
318 : : !! fft_test_print
319 : : !!
320 : : !! FUNCTION
321 : : !! Printout of the FFT_test_t structured datatype.
322 : : !!
323 : : !! INPUTS
324 : : !!
325 : : !! OUTPUT
326 : : !!
327 : : !! SOURCE
328 : :
329 : 98 : subroutine fft_test_print(Ftest, header, unit, mode_paral, prtvol)
330 : :
331 : : !Arguments -----------------------------------
332 : : class(FFT_test_t),intent(in) :: Ftest
333 : : integer,optional,intent(in) :: unit,prtvol
334 : : character(len=4),optional,intent(in) :: mode_paral
335 : : character(len=*),optional,intent(in) :: header
336 : :
337 : : !Local variables-------------------------------
338 : : !scalars
339 : : integer :: my_unt,my_prtvol
340 : : character(len=4) :: my_mode
341 : : character(len=500) :: msg
342 : : ! *********************************************************************
343 : :
344 : 0 : my_unt =std_out; if (PRESENT(unit )) my_unt =unit
345 : 98 : my_prtvol=0 ; if (PRESENT(prtvol )) my_prtvol=prtvol
346 [ - + ]: 98 : my_mode ='COLL' ; if (PRESENT(mode_paral)) my_mode =mode_paral
347 : :
348 : : !msg=' ==== Info on the FFT test object ==== '
349 [ - + ]: 98 : if (PRESENT(header)) then
350 [ # # # # ]: 0 : msg=' ==== '//TRIM(ADJUSTL(header))//' ==== '
351 : 0 : call wrtout(my_unt,msg,my_mode)
352 : : end if
353 : :
354 : 98 : write(msg,'(a,i3)')"FFT setup for fftalg ",Ftest%ngfft(7)
355 [ + + ]: 196 : call print_ngfft([my_unt], Ftest%ngfft, header=msg)
356 : :
357 [ - + ]: 98 : end subroutine fft_test_print
358 : : !!***
359 : :
360 : : !----------------------------------------------------------------------
361 : :
362 : : !!****f* m_FFT_prof/get_name
363 : : !! NAME
364 : : !! get_name
365 : : !!
366 : : !! FUNCTION
367 : : !! Returns a string with info on the test.
368 : : !!
369 : : !! INPUTS
370 : : !!
371 : : !! OUTPUT
372 : : !!
373 : : !! SOURCE
374 : :
375 : 403 : character(len=TNAME_LEN) function get_name(Ftest)
376 : :
377 : : !Arguments -----------------------------------
378 : : class(FFT_test_t),intent(in) :: Ftest
379 : :
380 : : !Local variables-------------------------------
381 : : character(len=TNAME_LEN) :: library_name,cplex_mode,padding_mode
382 : : ! *********************************************************************
383 : :
384 [ + - ]: 403 : if (ftest%gpu_option == 0) then
385 : 403 : call fftalg_info(Ftest%ngfft(7), library_name, cplex_mode, padding_mode)
386 : : !get_name = TRIM(library_name)//"; "//TRIM(cplex_mode)//"; "//TRIM(padding_mode)
387 : 403 : write(get_name,'(i3)')Ftest%ngfft(7)
388 [ + - ]: 403 : get_name = TRIM(library_name)//" ("//TRIM(get_name)//")"
389 : : else
390 : 0 : get_name = "GPU_FLAVOR"
391 : : end if
392 : :
393 : 403 : end function get_name
394 : : !!***
395 : :
396 : : !----------------------------------------------------------------------
397 : :
398 : : !!****f* m_FFT_prof/fftprof_init
399 : : !! NAME
400 : : !! fftprof_init
401 : : !!
402 : : !! FUNCTION
403 : : !! Creation method for the FFT_prof_t structured datatype.
404 : : !!
405 : : !! INPUTS
406 : : !! gflops = Gigaflops
407 : : !!
408 : : !! OUTPUT
409 : : !!
410 : : !! SOURCE
411 : :
412 [ + - - + : 403 : subroutine fftprof_init(Ftprof, test_name, nthreads, ncalls, ndat, gpu_option, cpu_time, wall_time, gflops, results)
+ - ]
413 : :
414 : : !Arguments -----------------------------------
415 : : class(FFT_prof_t),intent(out) :: Ftprof
416 : : integer,intent(in) :: ncalls,nthreads,ndat, gpu_option
417 : : real(dp),intent(in) :: cpu_time,wall_time,gflops
418 : : character(len=*),intent(in) :: test_name
419 : : !arrays
420 : : complex(dp),optional,intent(in) :: results(:)
421 : : ! *************************************************************************
422 : :
423 : 403 : Ftprof%ncalls = ncalls
424 : 403 : Ftprof%nthreads = nthreads
425 : 403 : Ftprof%ndat = ndat
426 : 403 : Ftprof%gpu_option = gpu_option
427 : 403 : Ftprof%cpu_time = cpu_time
428 : 403 : Ftprof%wall_time = wall_time
429 : 403 : Ftprof%gflops = gflops
430 [ - + ]: 403 : Ftprof%test_name = test_name
431 : :
432 [ + + ]: 403 : if (present(results)) then
433 [ - + - + : 921 : ABI_REMALLOC(Ftprof%results, (size(results)))
+ - + - +
- - + - +
- + ]
434 [ + - - + : 280722773 : Ftprof%results = results
- - + + ]
435 : : end if
436 : :
437 [ + + ]: 403 : end subroutine fftprof_init
438 : : !!***
439 : :
440 : : !----------------------------------------------------------------------
441 : :
442 : : !!****f* m_FFT_prof/fftprof_free_0D
443 : : !! NAME
444 : : !! fftprof_free_0D
445 : : !!
446 : : !! FUNCTION
447 : : !! Destruction method for the FFT_prof_t structured datatype.
448 : : !!
449 : : !! SOURCE
450 : :
451 : 501 : subroutine fftprof_free_0D(Ftprof)
452 : :
453 : : !Arguments -----------------------------------
454 : : class(FFT_prof_t),intent(inout) :: Ftprof
455 : : ! *********************************************************************
456 : :
457 [ + + ]: 501 : ABI_SFREE(Ftprof%results)
458 : :
459 : 501 : end subroutine fftprof_free_0D
460 : : !!***
461 : :
462 : : !----------------------------------------------------------------------
463 : :
464 : : !!****f* m_FFT_prof/fftprof_free_1D
465 : : !! NAME
466 : : !! fftprof_free_1D
467 : : !!
468 : : !! FUNCTION
469 : : !! Destruction method for the FFT_prof_t structured datatype.
470 : : !!
471 : : !! INPUTS
472 : : !!
473 : : !! OUTPUT
474 : : !!
475 : : !! SOURCE
476 : :
477 : 75 : subroutine fftprof_free_1D(Ftprof)
478 : :
479 : : !Arguments -----------------------------------
480 : : class(FFT_prof_t),intent(inout) :: Ftprof(:)
481 : :
482 : : !Local variables-------------------------------
483 : : integer :: ii
484 : : ! *********************************************************************
485 : :
486 [ + - + + ]: 651 : do ii=LBOUND(Ftprof,DIM=1),UBOUND(Ftprof,DIM=1)
487 : 576 : call fftprof_free_0D(Ftprof(ii))
488 : : end do
489 : :
490 : 75 : end subroutine fftprof_free_1D
491 : : !!***
492 : :
493 : : !----------------------------------------------------------------------
494 : :
495 : : !!****f* m_FFT_prof/fftprofs_print
496 : : !! NAME
497 : : !! fftprofs_print
498 : : !!
499 : : !! FUNCTION
500 : : !! Printout of the FFT_prof_t structured datatype.
501 : : !!
502 : : !! INPUTS
503 : : !!
504 : : !! OUTPUT
505 : : !!
506 : : !! SOURCE
507 : :
508 : 116 : subroutine fftprofs_print(Fprof, header, unit, mode_paral, prtvol)
509 : :
510 : : !Arguments -----------------------------------
511 : : class(FFT_prof_t),intent(in) :: Fprof(:)
512 : : integer,optional,intent(in) :: unit,prtvol
513 : : character(len=4),optional,intent(in) :: mode_paral
514 : : character(len=*),optional,intent(in) :: header
515 : :
516 : : !Local variables-------------------------------
517 : : !scalars
518 : : integer :: my_unt,my_prtvol,ncalls, field1_w,ii,ref_lib !ifft
519 : : real(dp) :: mabs_err,mean_err,check_mabs_err,check_mean_err, ref_wtime,para_eff
520 : : character(len=4) :: my_mode
521 : : character(len=500) :: ofmt,hfmt,nafmt,msg
522 : : ! *********************************************************************
523 : :
524 [ - + ]: 58 : my_unt =std_out; if (PRESENT(unit )) my_unt =unit
525 : 58 : my_prtvol=0 ; if (PRESENT(prtvol )) my_prtvol=prtvol
526 [ - + ]: 58 : my_mode ='COLL' ; if (PRESENT(mode_paral)) my_mode =mode_paral
527 : :
528 : 58 : msg='==== Info on the FFT_prof_t object ===='
529 [ + - + - : 58 : if (PRESENT(header)) msg='==== '//TRIM(ADJUSTL(header))//' ===='
+ - ]
530 : :
531 [ - + + + ]: 3506 : call wrtout(my_unt,ch10//REPEAT("=",LEN_TRIM(msg)))
532 : 58 : call wrtout(my_unt,msg,my_mode)
533 [ - + + + ]: 3506 : call wrtout(my_unt,REPEAT("=",LEN_TRIM(msg)))
534 : :
535 : 58 : field1_w=0 ! Width of the field used to print key names.
536 [ + + ]: 461 : do ii=1,SIZE(Fprof)
537 : 461 : field1_w = MAX(field1_w, LEN_TRIM(Fprof(ii)%test_name))
538 : : end do
539 : :
540 [ - + ]: 58 : if (field1_w==0) RETURN
541 : 58 : field1_w = field1_w + 2 ! To account for ". "
542 : 58 : write(ofmt,*)"(a",field1_w,",2x,2(f7.4,4x),1x,i2,1x,a,i3,a,1x,i0,4x,2(es9.2,3x))"
543 : :
544 : 58 : write(hfmt,*)"(a",field1_w,",2x,a)"
545 : 58 : write(std_out,hfmt)" Library ","CPU-time WALL-time nthreads ncalls Max_|Err| <|Err|>"
546 : : !
547 : : ! Find reference library.
548 : 58 : ref_lib=0
549 [ + - ]: 58 : do ii=1,SIZE(Fprof)
550 [ - + ]: 58 : if (Fprof(ii)%ncalls>0) then
551 : : ref_lib = ii
552 : : EXIT
553 : : end if
554 : : end do
555 : : !ref_lib=3
556 : : !
557 : : ! Write timing analysis and error wrt reference library if available.
558 : 58 : check_mabs_err=zero; check_mean_err=zero
559 [ + + ]: 461 : do ii=1,SIZE(Fprof)
560 : 403 : ncalls = Fprof(ii)%ncalls
561 [ + + ]: 461 : if (ncalls > 0) then
562 : 307 : mabs_err = zero; mean_err=zero
563 [ + - ]: 307 : if (ref_lib>0) then
564 [ + - - + : 280722773 : mabs_err = MAXVAL( ABS(Fprof(ii)%results - Fprof(ref_lib)%results) )
- - + + ]
565 [ + + ]: 280722466 : mean_err = SUM( ABS(Fprof(ii)%results - Fprof(ref_lib)%results) ) / SIZE(Fprof(ref_lib)%results)
566 : : ! Relative error is not a good estimator because some components are close to zero within machine accuracy.
567 : : !mean_err = 100 * MAXVAL( ABS(Fprof(ii)%results - Fprof(1)%results)/ ABS(Fprof(1)%results ))
568 : : !ifft = imax_loc( ABS(Fprof(ii)%results - Fprof(1)%results)/ ABS(Fprof(1)%results) )
569 : : !write(std_out,*) Fprof(ii)%results(ifft),Fprof(1)%results(ifft)
570 : : end if
571 [ + - ]: 307 : if (Fprof(ii)%nthreads==1) ref_wtime = Fprof(ii)%wall_time
572 : 307 : para_eff = 100 * ref_wtime / ( Fprof(ii)%wall_time * Fprof(ii)%nthreads)
573 : : write(std_out,ofmt)&
574 : 307 : "- "//Fprof(ii)%test_name,Fprof(ii)%cpu_time/ncalls,Fprof(ii)%wall_time/ncalls,&
575 : 614 : Fprof(ii)%nthreads,"(",NINT(para_eff),"%)",ncalls,mabs_err,mean_err
576 : 307 : check_mabs_err = MAX(check_mabs_err, mabs_err)
577 : 307 : check_mean_err = MAX(check_mean_err, mean_err)
578 : : else
579 : 96 : write(nafmt,*)"(a",field1_w,",2x,a)"
580 : 96 : write(std_out,nafmt)"- "//Fprof(ii)%test_name," N/A N/A N/A N/A N/A N/A"
581 : : end if
582 : : end do
583 : :
584 [ + - ]: 58 : if (ref_lib > 0) then
585 : : write(std_out,'(/,2(a,es9.2),2a)')&
586 : 58 : " Consistency check: MAX(Max_|Err|) = ",check_mabs_err,&
587 [ + - ]: 116 : ", Max(<|Err|>) = ",check_mean_err,", reference_lib: ",TRIM(Fprof(ref_lib)%test_name)
588 : : end if
589 : 58 : write(std_out,*)
590 : :
591 [ - + ]: 58 : end subroutine fftprofs_print
592 : : !!***
593 : :
594 : : !----------------------------------------------------------------------
595 : :
596 : : !!****f* m_FFT_prof/time_fourdp
597 : : !! NAME
598 : : !! time_fourdp
599 : : !!
600 : : !! FUNCTION
601 : : !! Profiling of the fourdp routine.
602 : : !!
603 : : !! INPUTS
604 : : !!
605 : : !! OUTPUT
606 : : !!
607 : : !! SOURCE
608 : :
609 : 16 : subroutine time_fourdp(Ftest, isign, cplex, header, Ftprof)
610 : :
611 : : !Arguments -----------------------------------
612 : : class(FFT_test_t),intent(inout) :: Ftest
613 : : integer,intent(in) :: cplex,isign
614 : : character(len=500),intent(out) :: header
615 : : class(FFT_prof_t),intent(out) :: Ftprof
616 : :
617 : : !Local variables-------------------------------
618 : : !scalars
619 : : integer,parameter :: nspinor1=1
620 : : integer :: icall,i1,i2,i3,n1,n2,n3,ifft
621 : : real(dp) :: cpu_time,wall_time,gflops,gsq
622 : : !character(len=500) :: msg
623 : : character(len=TNAME_LEN) :: test_name
624 : : !arrays
625 : : integer,parameter :: g0(3)=(/1,2,-1/)
626 : : integer :: gg(3)
627 : 16 : real(dp),allocatable :: fofg(:,:),fofr(:)
628 [ + - ]: 16 : complex(dp),allocatable :: results(:),ctmp(:)
629 : : ! *********************************************************************
630 : :
631 : 16 : test_name = Ftest%get_name()
632 : 16 : n1=Ftest%ngfft(1); n2=Ftest%ngfft(2); n3=Ftest%ngfft(3)
633 : :
634 : 16 : write(header,'(2(a,i2),a)')" fourdp with cplex ",cplex,", isign ",isign,", ndat 1"
635 : :
636 [ + + ]: 16 : if (Ftest%available == 0) then
637 : 4 : call Ftprof%init(test_name,0,0,0,0,zero,zero,zero)
638 : : RETURN
639 : : end if
640 : :
641 : 12 : call xomp_set_num_threads(Ftest%nthreads)
642 : :
643 [ - + ]: 12 : if (Ftest%ngfft(7)/100 == FFT_FFTW3) call fftw3_set_nthreads(Ftest%nthreads)
644 : :
645 [ - + + - : 36 : ABI_MALLOC(fofg,(2,Ftest%nfft))
+ - + - -
+ - + ]
646 [ - + + - : 36 : ABI_MALLOC(fofr,(cplex*Ftest%nfft))
+ - + - -
+ - + ]
647 : :
648 : : ! Initialize input data.
649 [ + + ]: 12 : if (isign==1) then
650 : : ! initialize fofg
651 [ + + + + ]: 13122006 : fofg = zero
652 : : ifft=0
653 [ + + ]: 546 : do i3=1,n3
654 [ + + ]: 540 : gg(3)=i3-1; if (i3>1+n3/2) gg(3)=i3-n3-1 ! TODO recheck this
655 [ + + ]: 49146 : do i2=1,n2
656 [ + + ]: 48600 : gg(2)=i2-1; if (i2>1+n2/2) gg(2)=i2-n2-1
657 [ + + ]: 4423140 : do i1=1,n1
658 [ + + ]: 4374000 : gg(1)=i1-1; if (i1>1+n1/2) gg(1)=i1-n1-1
659 [ + + + + : 83106000 : gsq = two_pi**2 * DOT_PRODUCT(gg,MATMUL(Ftest%gmet,gg))
+ + + + ]
660 : 4374000 : ifft=ifft+1
661 : 4374000 : fofg(1,ifft) = EXP(-gsq)
662 : 4422600 : fofg(2,ifft) = zero
663 : : end do
664 : : end do
665 : : end do
666 : :
667 : : else
668 : : ! init fofr
669 [ + + ]: 6 : if (cplex==2) then
670 : 3 : call calc_eigr(g0,Ftest%nfft,Ftest%ngfft,fofr)
671 [ + - ]: 3 : else if (cplex==1) then
672 [ - + + - : 9 : ABI_MALLOC(ctmp,(Ftest%nfft))
+ - + - -
+ - + ]
673 : 3 : call calc_ceigr(g0,Ftest%nfft,nspinor1,Ftest%ngfft,ctmp)
674 [ + - - + : 2187006 : fofr = REAL(ctmp)
- - + + ]
675 [ - + ]: 3 : ABI_FREE(ctmp)
676 : : else
677 : 0 : ABI_ERROR(sjoin("Wrong cplex:", itoa(cplex)))
678 : : end if
679 : : end if
680 : :
681 [ - + + - : 8748036 : ABI_CALLOC(results, (Ftest%nfft))
+ - + - -
+ - + +
+ ]
682 : 12 : call cwtime(cpu_time, wall_time, gflops, "start")
683 : :
684 [ + + ]: 72 : do icall=1,NCALLS_FOR_TEST
685 : 60 : ifft = empty_cache(CACHE_KBSIZE)
686 : 60 : call fourdp(cplex,fofg,fofr,isign,Ftest%MPI_enreg,Ftest%nfft,1,Ftest%ngfft,0)
687 : :
688 : : ! Store results at the first call.
689 [ + + ]: 72 : if (icall==1) then
690 [ + + ]: 12 : if (isign==1) then
691 [ + + ]: 6 : if (cplex==1) then
692 [ + - - + : 2187006 : results = DCMPLX(fofr, zero)
- - + + ]
693 [ + - ]: 3 : else if (cplex==2) then
694 [ + - - + : 2187006 : results = DCMPLX( fofr(1:2*Ftest%nfft:2), fofr(2:2*Ftest%nfft:2) )
- - + + ]
695 : : end if
696 [ + - ]: 6 : else if (isign==-1) then
697 [ + - - + : 4374012 : results = DCMPLX(fofg(1,:),fofg(2,:))
- - + + ]
698 : : end if
699 : : end if
700 : : end do
701 : :
702 : 12 : call cwtime(cpu_time, wall_time, gflops, "stop")
703 : : call Ftprof%init(test_name,Ftest%nthreads,NCALLS_FOR_TEST,Ftest%ndat,ftest%gpu_option, &
704 : 12 : cpu_time,wall_time,gflops,results=results)
705 : :
706 [ - + ]: 12 : ABI_FREE(fofg)
707 [ - + ]: 12 : ABI_FREE(fofr)
708 [ - + ]: 12 : ABI_FREE(results)
709 : :
710 : 24 : end subroutine time_fourdp
711 : : !!***
712 : :
713 : : !----------------------------------------------------------------------
714 : :
715 : : !!****f* m_FFT_prof/time_fftbox
716 : : !! NAME
717 : : !! time_fftbox
718 : : !!
719 : : !! FUNCTION
720 : : !! Profiling of the fftbox_[io]p routines.
721 : : !!
722 : : !! INPUTS
723 : : !!
724 : : !! OUTPUT
725 : : !!
726 : : !! SOURCE
727 : :
728 : 12 : subroutine time_fftbox(Ftest, isign, inplace, header, Ftprof)
729 : :
730 : : !Arguments -----------------------------------
731 : : class(FFT_test_t),intent(inout) :: Ftest
732 : : integer,intent(in) :: isign,inplace
733 : : character(len=500),intent(inout) :: header
734 : : class(FFT_prof_t),intent(out) :: Ftprof
735 : :
736 : : !Local variables-------------------------------
737 : : !scalars
738 : : integer,parameter :: nspinor1 = 1, fftcache0 = 0
739 : : integer :: icall,i1,i2,i3,n1,n2,n3,ifft,ndat,nfft,dat,padat
740 : : real(dp) :: cpu_time,wall_time,gflops,gsq
741 : : !character(len=500) :: msg
742 : : character(len=TNAME_LEN) :: test_name
743 : : type(fftbox_plan3_t) :: plan
744 : : !arrays
745 : : integer,parameter :: g0(3) = [1,-2,1]
746 : : integer :: gg(3)
747 : 12 : complex(dp),allocatable :: ffc(:),ggc(:),results(:)
748 : : ! *********************************************************************
749 : :
750 : 12 : test_name = Ftest%get_name()
751 : :
752 [ + + ]: 12 : if (Ftest%available == 0) then
753 : 4 : call Ftprof%init(test_name, 0, 0, 0, 0, zero, zero, zero)
754 : : return
755 : : end if
756 : :
757 : 8 : call xomp_set_num_threads(Ftest%nthreads)
758 : :
759 [ - + ]: 8 : if (Ftest%ngfft(7)/100 == FFT_FFTW3) call fftw3_set_nthreads(Ftest%nthreads)
760 : :
761 : 8 : n1 = Ftest%ngfft(1); n2 = Ftest%ngfft(2); n3 = Ftest%ngfft(3)
762 : 8 : nfft = Ftest%nfft; ndat = Ftest%ndat
763 : 8 : write(header,'(3(a,i2))')" fftbox with isign ",isign,", in-place ",inplace,", ndat ",ndat
764 : :
765 [ - + + - : 5832024 : ABI_CALLOC(ffc, (nfft*ndat))
+ - + - -
+ - + +
+ ]
766 [ - + + - : 5832016 : ABI_CALLOC(ggc, (nfft*ndat))
- + - + +
+ ]
767 [ - + + - : 5832016 : ABI_CALLOC(results, (nfft*ndat))
- + - + +
+ ]
768 : :
769 [ + + ]: 8 : if (isign==-1) then
770 : 4 : call calc_ceigr(g0,nfft,nspinor1,Ftest%ngfft,ffc)
771 [ + - ]: 4 : else if (isign==1) then
772 : : ifft=0
773 [ + + ]: 364 : do i3=1,n3
774 [ + + ]: 360 : gg(3)=i3-1; if (i3>1+n3/2) gg(3)=i3-n3-1 ! TODO recheck this
775 [ + + ]: 32764 : do i2=1,n2
776 [ + + ]: 32400 : gg(2)=i2-1; if (i2>1+n2/2) gg(2)=i2-n2-1
777 [ + + ]: 2948760 : do i1=1,n1
778 [ + + ]: 2916000 : gg(1)=i1-1; if (i1>1+n1/2) gg(1)=i1-n1-1
779 [ + + + + : 55404000 : gsq = two_pi**2 * DOT_PRODUCT(gg,MATMUL(Ftest%gmet,gg))
+ + + + ]
780 : 2916000 : ifft=ifft+1
781 : 2948400 : ffc(ifft) = EXP(-gsq)
782 : : end do
783 : : end do
784 : : end do
785 : : else
786 : 0 : ABI_ERROR("Wrong isign")
787 : : end if
788 : :
789 : : ! Replicate and scale input data
790 [ - + ]: 8 : do dat=2,ndat
791 : 0 : padat = (dat-1) * nfft
792 [ - - ]: 8 : do ifft=1,nfft
793 : 0 : ffc(ifft+padat) = DBLE(dat) * ffc(ifft)
794 : : end do
795 : : end do
796 : :
797 : 8 : call cwtime(cpu_time, wall_time, gflops, "start")
798 : :
799 : : ! No augmentation here.
800 : 8 : call plan%init(ndat, Ftest%ngfft(1:3), Ftest%ngfft(1:3), Ftest%ngfft(7), fftcache0, ftest%gpu_option)
801 : :
802 : : if (plan%gpu_option == ABI_GPU_OPENMP) then
803 : : #ifdef HAVE_OPENMP_OFFLOAD
804 : : !$OMP TARGET ENTER DATA MAP(to:ffc, ggc)
805 : : #endif
806 : : end if
807 : :
808 : 12 : select case (inplace)
809 : : case (0)
810 [ + + ]: 24 : do icall=1,NCALLS_FOR_TEST
811 : 20 : ifft = empty_cache(CACHE_KBSIZE)
812 : 20 : call plan%execute(ffc, ggc, isign, ndat, iscale=0)
813 : : ! Store results at the first call.
814 [ + + ]: 24 : if (icall == 1) then
815 : : #ifdef HAVE_OPENMP_OFFLOAD
816 : : !$omp target update from(ggc)
817 : : #endif
818 [ + - - + : 2916008 : results = ggc
- - + + ]
819 : : end if
820 : : end do
821 : : case (1)
822 [ + + ]: 24 : do icall=1,NCALLS_FOR_TEST
823 : 20 : ifft = empty_cache(CACHE_KBSIZE)
824 : 20 : call plan%execute(ffc, isign, ndat, iscale=0)
825 : : ! Store results at the first call.
826 [ + + ]: 24 : if (icall == 1) then
827 : : #ifdef HAVE_OPENMP_OFFLOAD
828 : : !$omp target update from(ffc)
829 : : #endif
830 [ + - - + : 2916008 : results = ffc
- - + + ]
831 : : end if
832 : : end do
833 : : case default
834 [ + + - ]: 8 : ABI_ERROR(sjoin("Wrong value for inplace:", itoa(inplace)))
835 : : end select
836 : :
837 : 8 : call cwtime(cpu_time, wall_time, gflops, "stop")
838 : : call Ftprof%init(test_name,Ftest%nthreads,NCALLS_FOR_TEST,Ftest%ndat,ftest%gpu_option, &
839 : 8 : cpu_time,wall_time,gflops,results=results)
840 : :
841 : 8 : call plan%free()
842 : :
843 : : if (plan%gpu_option == ABI_GPU_OPENMP) then
844 : : #ifdef HAVE_OPENMP_OFFLOAD
845 : : !$OMP TARGET EXIT DATA MAP(delete:ffc, ggc)
846 : : #endif
847 : : end if
848 [ - + ]: 8 : ABI_FREE(ffc)
849 [ - + ]: 8 : ABI_FREE(ggc)
850 [ - + ]: 8 : ABI_FREE(results)
851 : :
852 [ + + + + : 100 : end subroutine time_fftbox
+ - ]
853 : : !!***
854 : :
855 : : !----------------------------------------------------------------------
856 : :
857 : : !!****f* m_FFT_prof/time_fourwf
858 : : !! NAME
859 : : !! time_fourwf
860 : : !!
861 : : !! FUNCTION
862 : : !! Profiling of the fourwf routine.
863 : : !!
864 : : !! INPUTS
865 : : !!
866 : : !! OUTPUT
867 : : !!
868 : : !! SOURCE
869 : :
870 : 363 : subroutine time_fourwf(Ftest, cplex, option_fourwf, header, Ftprof)
871 : :
872 : : !Arguments -----------------------------------
873 : : class(FFT_test_t),intent(inout) :: Ftest
874 : : integer,intent(in) :: cplex,option_fourwf
875 : : character(len=500),intent(out) :: header
876 : : class(FFT_prof_t),intent(out) :: Ftprof
877 : :
878 : : !Local variables-------------------------------
879 : : !scalars
880 : : integer,parameter :: tim0=0
881 : : integer :: n1,n2,n3,n4,n5,n6,npw_out,icall,i1,i2,i3,idx,ipw,ndat,cnt,dat,padat
882 : : integer :: fftalg,fftalga,fftalgc
883 : : real(dp),parameter :: weight_i=one,weight_r=one
884 : : real(dp) :: cpu_time,wall_time,gflops,gsq,g0dotr
885 : : logical :: isbuggy,not_supported
886 : : !character(len=500) :: msg
887 : : character(len=TNAME_LEN) :: test_name
888 : : !arrays
889 : : integer,parameter :: g0(3)=[1,-1,2] !g0(3)=[1,0,0]
890 : : integer :: gg(3)
891 : 363 : integer,allocatable :: gbound_in(:,:),gbound_out(:,:)
892 : 363 : real(dp),allocatable :: denpot(:,:,:),fofg_in(:,:), fofr_4(:,:,:,:),fofg_out(:,:)
893 [ + - ]: 363 : complex(dp),allocatable :: results(:)
894 : : ! *********************************************************************
895 : :
896 : 363 : test_name = Ftest%get_name()
897 : :
898 : 363 : fftalg = Ftest%ngfft(7); fftalga = fftalg/100; fftalgc = MOD(fftalg,10)
899 : :
900 : : isbuggy = &
901 : : (option_fourwf==3 .and. fftalga==FFT_SG2002 .and. fftalgc /= 0 .and. &
902 [ + + + + : 2008 : any(Ftest%istwf_k == [3,4,5,6,7,8,9])) ! see sg_fourwf
+ + + + +
+ ]
903 : : !isbuggy = .False.
904 : :
905 : : !FIXME problems with the unitary tests reference files!
906 : : not_supported = ( &
907 [ + + + + : 363 : (fftalgc == 2 .and. option_fourwf==0 .and. Ftest%istwf_k > 2))
+ + ]
908 : : !not_supported = .FALSE.
909 : :
910 : 363 : npw_out= Ftest%npw_kout
911 : 363 : ndat = Ftest%ndat
912 : 363 : n1=Ftest%ngfft(1); n2=Ftest%ngfft(2); n3=Ftest%ngfft(3)
913 : 363 : n4=Ftest%ngfft(4); n5=Ftest%ngfft(5); n6=Ftest%ngfft(6)
914 : :
915 : 363 : write(header,'(4(a,i2))')" fourwf with option ",option_fourwf,", cplex ",cplex,", ndat ",ndat,", istwf_k ",Ftest%istwf_k
916 : :
917 [ + + + + ]: 363 : if (isbuggy .or. not_supported .or. Ftest%available==0) then
918 : 81 : call Ftprof%init(test_name,0,0,0,0,zero,zero,zero)
919 : 81 : RETURN
920 : : end if
921 : :
922 : 282 : call xomp_set_num_threads(Ftest%nthreads)
923 : :
924 [ - + ]: 282 : if (Ftest%ngfft(7)/100 == FFT_FFTW3) call fftw3_set_nthreads(Ftest%nthreads)
925 : :
926 : : ! FFTW3 does not need gbound_in but oh well
927 [ + - - + : 1128 : ABI_MALLOC(gbound_in, (2*Ftest%mgfft+8,2))
+ - + - +
- + - - +
- + ]
928 : 282 : call sphereboundary(gbound_in,Ftest%istwf_k,Ftest%kg_k,Ftest%mgfft,Ftest%npw_k)
929 : :
930 [ + - - + : 1128 : ABI_MALLOC(gbound_out, (2*Ftest%mgfft+8,2))
+ - + - +
- + - - +
- + ]
931 : 282 : call sphereboundary(gbound_out,Ftest%istwf_k,Ftest%kg_kout,Ftest%mgfft,Ftest%npw_kout)
932 : :
933 [ + + + - : 118451490 : ABI_CALLOC(denpot, (cplex*n4,n5,n6))
- + + - -
+ + - + -
+ + - + -
+ + + + +
+ + ]
934 [ - + + - : 38832138 : ABI_CALLOC(fofg_in, (2,Ftest%npw_k*ndat))
+ - + - -
+ - + + +
+ + ]
935 [ - + + - : 38832138 : ABI_CALLOC(fofg_out, (2,npw_out*ndat))
+ - + - -
+ - + + +
+ + ]
936 [ - + + - : 811367790 : ABI_CALLOC(fofr_4, (2,n4,n5,n6*ndat))
- + + - -
+ + - + -
+ - - + -
+ + + + +
+ + + + ]
937 [ - + + - : 264648846 : ABI_CALLOC(results, (Ftest%nfft*ndat))
+ - + - -
+ - + +
+ ]
938 : :
939 : : select case (option_fourwf)
940 : : case (0, 1, 2)
941 : : !! for option==0, fofgin(2,npwin*ndat)=holds input wavefunction in G sphere;
942 : : !! fofr(2,n4,n5,n6) contains the output Fourier Transform of fofgin;
943 : : !! no use of denpot, fofgout and npwout.
944 : : !! for option==1, fofgin(2,npwin*ndat)=holds input wavefunction in G sphere;
945 : : !! denpot(cplex*n4,n5,n6) contains the input density at input,
946 : : !! and the updated density at output (accumulated);
947 : : !! no use of fofgout and npwout.
948 : : !! for option==2, fofgin(2,npwin*ndat)=holds input wavefunction in G sphere;
949 : : !! denpot(cplex*n4,n5,n6) contains the input local potential;
950 : : !! fofgout(2,npwout*ndat) contains the output function;
951 : : !!
952 [ + + ]: 10259385 : do cnt=0, (Ftest%npw_k * ndat) - 1
953 : 10259165 : ipw = 1 + MOD(cnt, Ftest%npw_k)
954 [ + + ]: 41036660 : gg = Ftest%kg_k(:,ipw)
955 [ + + + + : 194924135 : gsq = two_pi**2 * DOT_PRODUCT(gg,MATMUL(Ftest%gmet,gg))
+ + + + ]
956 : 10259165 : fofg_in(1,cnt+1) = EXP(-gsq)
957 : 10259385 : fofg_in(2,cnt+1) = zero
958 : : end do
959 : :
960 [ + + + + : 45465740 : if (option_fourwf==1) denpot = one
+ + + + ]
961 : :
962 [ + + ]: 220 : if (option_fourwf==2) then
963 : : ! Init denpot
964 [ + + ]: 89 : if (cplex==1) then
965 [ + + ]: 6556 : do i3=0,n3-1
966 [ + + ]: 529116 : do i2=0,n2-1
967 [ + + ]: 44721040 : do i1=0,n1-1
968 : : g0dotr= two_pi*( g0(1)*(i1/DBLE(n1)) &
969 : : +g0(2)*(i2/DBLE(n2)) &
970 : 44192000 : +g0(3)*(i3/DBLE(n3)) )
971 : 44714560 : denpot(i1+1,i2+1,i3+1)=COS(g0dotr)
972 : : end do
973 : : end do
974 : : end do
975 [ + - ]: 13 : else if (cplex==2) then
976 [ + + ]: 1313 : do i3=0,n3-1
977 [ + + ]: 131313 : do i2=0,n2-1
978 : : idx=1
979 [ + + ]: 13131300 : do i1=0,n1-1
980 : : g0dotr= two_pi*( g0(1)*(i1/DBLE(n1)) &
981 : : +g0(2)*(i2/DBLE(n2)) &
982 : 13000000 : +g0(3)*(i3/DBLE(n3)) )
983 : :
984 : 13000000 : denpot(idx, i2+1,i3+1)= COS(g0dotr)
985 : 13000000 : denpot(idx+1,i2+1,i3+1)= SIN(g0dotr)
986 : 13130000 : idx=idx+2
987 : : end do
988 : : end do
989 : : end do
990 : : end if
991 : : end if
992 : :
993 : : case (3)
994 : : !! for option==3, fofr(2,n4,n5,n6*ndat) contains the input real space wavefunction;
995 : : !! fofgout(2,npwout*ndat) contains its output Fourier transform;
996 : : !! no use of fofgin and npwin.
997 : : idx=0
998 [ + + ]: 142 : do dat=1,ndat
999 : 80 : padat = (dat-1)*n6
1000 [ + + ]: 7302 : do i3=0,n3-1
1001 [ + + ]: 629160 : do i2=0,n2-1
1002 [ + + ]: 56773080 : do i1=0,n1-1
1003 : : g0dotr= two_pi*( g0(1)*(i1/DBLE(n1)) &
1004 : : +g0(2)*(i2/DBLE(n2)) &
1005 : 56144000 : +g0(3)*(i3/DBLE(n3)) )
1006 : : !fofr_4(1,i1+1,i2+1,i3+1+padat)=COS(g0dotr)
1007 : : !fofr_4(2,i1+1,i2+1,i3+1+padat)=SIN(g0dotr)
1008 : 56144000 : fofr_4(1,i1+1,i2+1,i3+1+padat)=10 * EXP(-g0dotr**2)
1009 : 56144000 : fofr_4(2,i1+1,i2+1,i3+1+padat)=zero
1010 : 56144000 : idx=idx+1
1011 : 56765920 : results(idx) = DCMPLX(fofr_4(1,i1+1,i2+1,i3+1+padat), fofr_4(2,i1+1,i2+1,i3+1+padat))
1012 : : end do
1013 : : end do
1014 : : end do
1015 : : end do
1016 : :
1017 : : case default
1018 [ + + - ]: 282 : ABI_ERROR(sjoin("Wrong value for option_fourwf:", itoa(option_fourwf)))
1019 : : end select
1020 : :
1021 : 282 : call cwtime(cpu_time, wall_time, gflops, "start")
1022 : :
1023 [ + + ]: 1602 : do icall=1,NCALLS_FOR_TEST
1024 : :
1025 : 1320 : i1 = empty_cache(CACHE_KBSIZE)
1026 : :
1027 : : call fourwf(cplex,denpot,fofg_in,fofg_out,fofr_4,gbound_in,gbound_out,Ftest%istwf_k,&
1028 : : Ftest%kg_k,Ftest%kg_kout,Ftest%mgfft,Ftest%MPI_enreg,ndat,Ftest%ngfft,Ftest%npw_k,npw_out,n4,n5,n6,option_fourwf,&
1029 : 1320 : tim0,weight_r,weight_i, gpu_option=ftest%gpu_option)
1030 : :
1031 : : ! Store results at the first call.
1032 [ + + ]: 1602 : if (icall == 1) then
1033 : : select case (option_fourwf)
1034 : : case (0)
1035 : : !! for option==0, fofgin(2,npwin*ndat)=holds input wavefunction in G sphere;
1036 : : !! fofr(2,n4,n5,n6) contains the output Fourier Transform of fofgin;
1037 : : !! no use of denpot, fofgout and npwout.
1038 : : idx=0
1039 [ + + ]: 128 : do dat=1,ndat
1040 : 73 : padat = (dat-1)*n6
1041 [ + + ]: 6728 : do i3=1,n3
1042 [ + + ]: 588273 : do i2=1,n2
1043 [ + + ]: 53708200 : do i1=1,n1
1044 : 53120000 : idx=idx+1
1045 : 53701600 : results(idx) = DCMPLX(fofr_4(1,i1,i2,i3+padat),fofr_4(2,i1,i2,i3+padat))
1046 : : end do
1047 : : end do
1048 : : end do
1049 : : end do
1050 : : case (1)
1051 : : !! for option==1, fofgin(2,npwin*ndat)=holds input wavefunction in G sphere;
1052 : : !! denpot(cplex*n4,n5,n6) contains the input density at input,
1053 : : !! and the updated density at output (accumulated);
1054 : : !! no use of fofgout and npwout.
1055 [ + - ]: 76 : if (cplex==1) then
1056 : : idx=0
1057 [ + + ]: 6556 : do i3=1,n3
1058 [ + + ]: 529116 : do i2=1,n2
1059 [ + + ]: 44721040 : do i1=1,n1
1060 : 44192000 : idx=idx+1
1061 : 44714560 : results(idx) = DCMPLX(denpot(i1,i2,i3),zero)
1062 : : end do
1063 : : end do
1064 : : end do
1065 : :
1066 [ # # ]: 0 : else if (cplex==2) then
1067 : : idx=0
1068 [ # # ]: 0 : do i3=1,n3
1069 [ # # ]: 0 : do i2=1,n2
1070 [ # # ]: 0 : do i1=1,2*n1,2
1071 : 0 : idx=idx+1
1072 [ # # ]: 0 : results(idx) = DCMPLX(denpot(i1,i2,i3),denpot(i1+1,i2,i3))
1073 : : end do
1074 : : end do
1075 : : end do
1076 : : else
1077 : 0 : ABI_ERROR("Wrong cplex")
1078 : : end if
1079 : :
1080 : : case (2)
1081 : : !! for option==2, fofgin(2,npwin*ndat)=holds input wavefunction in G sphere;
1082 : : !! denpot(cplex*n4,n5,n6) contains the input local potential;
1083 : : !! fofgout(2,npwout*ndat) contains the output function;
1084 [ + + ]: 4803443 : do ipw=1,npw_out*ndat
1085 : 4803443 : results(ipw) = DCMPLX(fofg_out(1,ipw),fofg_out(2,ipw))
1086 : : end do
1087 : :
1088 : : case (3)
1089 : : !! for option==3, fofr(2,n4,n5,n6*ndat) contains the input real space wavefunction;
1090 : : !! fofgout(2,npwout*ndat) contains its output Fourier transform;
1091 : : !! no use of fofgin and npwin.
1092 [ + + + + : 2684881 : do ipw=1,npw_out*ndat
- + + ]
1093 : 2684661 : results(ipw) = DCMPLX(fofg_out(1,ipw),fofg_out(2,ipw))
1094 : : end do
1095 : : !write(Ftest%ngfft(7),*)"results opt 3 Ftest%ngfft(7)",Ftest%ngfft(7)
1096 : : !do dat=1,ndat
1097 : : ! do ipw=1,npw_out
1098 : : ! idx = ipw + (dat-1)*npw_out
1099 : : ! write(Ftest%ngfft(7),*)ipw,dat,results(idx)
1100 : : ! end do
1101 : : !end do
1102 : : end select
1103 : : end if
1104 : : end do
1105 : :
1106 : 282 : call cwtime(cpu_time, wall_time, gflops, "stop")
1107 : : call Ftprof%init(test_name,Ftest%nthreads,NCALLS_FOR_TEST,Ftest%ndat,ftest%gpu_option,&
1108 : 282 : cpu_time,wall_time,gflops,results=results)
1109 : :
1110 [ - + ]: 282 : ABI_FREE(denpot)
1111 [ - + ]: 282 : ABI_FREE(fofg_in)
1112 [ - + ]: 282 : ABI_FREE(fofg_out)
1113 [ - + ]: 282 : ABI_FREE(fofr_4)
1114 [ - + ]: 282 : ABI_FREE(gbound_in)
1115 [ - + ]: 282 : ABI_FREE(gbound_out)
1116 [ - + ]: 282 : ABI_FREE(results)
1117 : :
1118 [ - + ]: 927 : end subroutine time_fourwf
1119 : : !!***
1120 : :
1121 : : !----------------------------------------------------------------------
1122 : :
1123 : : !!****f* m_FFT_prof/fftprof_ncalls_per_test
1124 : : !! NAME
1125 : : !! fftprof_ncalls_per_test
1126 : : !!
1127 : : !! FUNCTION
1128 : : !! Helper function used to set the number of calls to be used in each time_* routine.
1129 : : !!
1130 : : !! INPUTS
1131 : : !! ncalls=Number of calls to be used.
1132 : : !!
1133 : : !! SIDE EFFECTS
1134 : : !! NCALLS_FOR_TEST = ncalls
1135 : : !!
1136 : : !! SOURCE
1137 : :
1138 : 17 : subroutine fftprof_ncalls_per_test(ncalls)
1139 : :
1140 : : !Arguments -----------------------------------
1141 : : integer,intent(in) :: ncalls
1142 : : ! *********************************************************************
1143 : :
1144 : 17 : NCALLS_FOR_TEST = ncalls
1145 : :
1146 : 17 : end subroutine fftprof_ncalls_per_test
1147 : : !!***
1148 : :
1149 : : !----------------------------------------------------------------------
1150 : :
1151 : : !!****f* m_FFT_prof/time_rhotwg
1152 : : !! NAME
1153 : : !! time_rhotwg
1154 : : !!
1155 : : !! FUNCTION
1156 : : !! Profiling of the rho_tw_g routine.
1157 : : !!
1158 : : !! INPUTS
1159 : : !!
1160 : : !! OUTPUT
1161 : : !!
1162 : : !! SOURCE
1163 : :
1164 : 6 : subroutine time_rhotwg(Ftest, map2sphere, use_padfft, osc_npw, osc_gvec, header, Ftprof)
1165 : :
1166 : : !Arguments -----------------------------------
1167 : : !scalars
1168 : : class(FFT_test_t),intent(inout) :: Ftest
1169 : : integer,intent(in) :: map2sphere,use_padfft,osc_npw
1170 : : character(len=500),intent(out) :: header
1171 : : class(FFT_prof_t),intent(out) :: Ftprof
1172 : : !arrays
1173 : : integer,intent(in) :: osc_gvec(3,osc_npw)
1174 : :
1175 : : !Local variables-------------------------------
1176 : : !scalars
1177 : : integer,parameter :: nspinor1=1,dim_rtwg1=1,istwfk1=1
1178 : : integer :: icall,ifft,itim1,itim2,nfft,dat,sprc,ptr,ndat, n1,n2,n3,n4,n5,n6
1179 : : real(dp) :: cpu_time,wall_time,gflops
1180 : : complex(dp) :: ktabp1 = cone, ktabp2 = cone
1181 : : character(len=TNAME_LEN) :: test_name
1182 : : logical :: not_implemented
1183 : 6 : type(MPI_type) :: MPI_enreg_seq
1184 : : !arrays
1185 : : !integer,parameter :: g1(3)=[1,1,2],g2(3)=[-1,-2,-1]
1186 : : integer,parameter :: g1(3)=[-1,0,0], g2(3)=[1,0,0]
1187 : 6 : integer,allocatable :: gbound(:,:), ktabr1(:), ktabr2(:), igfftg0(:)
1188 : : real(dp),parameter :: spinrot1(4)=(/one,zero,zero,one/),spinrot2(4)=(/one,zero,zero,one/)
1189 : 6 : logical,allocatable :: mask(:)
1190 : 6 : complex(dp),allocatable :: results(:)
1191 [ + - ]: 6 : complex(gwp),allocatable :: rhotwg(:), wfn1(:), wfn2(:)
1192 : : ! *********************************************************************
1193 : :
1194 : 6 : test_name = Ftest%get_name()
1195 : :
1196 : 6 : nfft = Ftest%nfft; ndat = Ftest%ndat
1197 : 6 : n1=Ftest%ngfft(1); n2=Ftest%ngfft(2); n3=Ftest%ngfft(3)
1198 : 6 : n4=Ftest%ngfft(4); n5=Ftest%ngfft(5); n6=Ftest%ngfft(6)
1199 : :
1200 : 6 : write(header,'(3(a,i2))')"rho_tw_g with use_padfft ",use_padfft,", map2sphere ",map2sphere,", ndat ",ndat
1201 : :
1202 : : ! TODO: zero-pad not available with SG2001 routines.
1203 [ + + + + ]: 6 : not_implemented = (use_padfft==1.and.Ftest%ngfft(7) == 412)
1204 : :
1205 [ + + + + ]: 6 : if (Ftest%available==0.or.not_implemented) then
1206 : 3 : call Ftprof%init(test_name,0,0,0,0,zero,zero,zero)
1207 : 3 : return
1208 : : end if
1209 : :
1210 : 3 : call xomp_set_num_threads(Ftest%nthreads)
1211 : :
1212 [ - + ]: 3 : if (Ftest%ngfft(7)/100 == FFT_FFTW3) call fftw3_set_nthreads(Ftest%nthreads)
1213 : :
1214 : 3 : call initmpi_seq(MPI_enreg_seq)
1215 : 3 : call MPI_enreg_seq%distribfft%init_seq('c',n2,n3,'all')
1216 : :
1217 : 3 : itim1=1; itim2=1
1218 [ - + + - : 9 : ABI_MALLOC(ktabr1,(nfft))
+ - + - -
+ - + ]
1219 [ - + + - : 6 : ABI_MALLOC(ktabr2,(nfft))
- + - + ]
1220 : :
1221 [ + + ]: 2187003 : do ifft=1,nfft
1222 : 2187000 : ktabr1(ifft)= ifft
1223 : 2187003 : ktabr2(ifft)= ifft
1224 : : end do
1225 : :
1226 [ - + + - : 9 : ABI_MALLOC(igfftg0,(osc_npw*map2sphere))
+ - + - -
+ - + ]
1227 : :
1228 [ + - ]: 3 : if (map2sphere > 0) then
1229 [ - + + - : 9 : ABI_MALLOC(mask,(osc_npw))
+ - + - -
+ - + ]
1230 : 3 : call kgindex(igfftg0,osc_gvec,mask,MPI_enreg_seq,Ftest%ngfft,osc_npw)
1231 [ + + + - : 36162 : ABI_CHECK(ALL(mask)," FFT parallelism not supported")
- + ]
1232 [ - + ]: 3 : ABI_FREE(mask)
1233 : : end if
1234 : :
1235 [ + - - + : 12 : ABI_MALLOC(gbound,(2*Ftest%mgfft+8,2*use_padfft))
+ - + + +
+ + - + -
+ + - + -
+ ]
1236 [ + + ]: 3 : if (use_padfft == 1) call sphereboundary(gbound,istwfk1,osc_gvec,Ftest%mgfft,osc_npw)
1237 : :
1238 [ - + + - : 9 : ABI_MALLOC(wfn1, (nfft*nspinor1*ndat))
+ - + - -
+ - + ]
1239 [ - + + - : 6 : ABI_MALLOC(wfn2, (nfft*nspinor1*ndat))
- + - + ]
1240 : :
1241 [ + + ]: 6 : do dat=1,ndat
1242 [ + + ]: 9 : do sprc=1,nspinor1
1243 : 3 : ptr = 1 + (sprc-1)*nfft + (dat-1)*nfft*nspinor1
1244 : 3 : call calc_ceigr(g1,nfft,nspinor1,Ftest%ngfft,wfn1(ptr:))
1245 : 6 : call calc_ceigr(g2,nfft,nspinor1,Ftest%ngfft,wfn2(ptr:))
1246 : : end do
1247 : : end do
1248 : :
1249 [ - + + - : 9 : ABI_MALLOC(rhotwg,(osc_npw*dim_rtwg1*ndat))
+ - + - -
+ - + ]
1250 [ - + + - : 6 : ABI_MALLOC(results,(osc_npw*dim_rtwg1*ndat))
- + - + ]
1251 : :
1252 : 3 : call cwtime(cpu_time, wall_time, gflops, "start")
1253 : :
1254 [ + + ]: 18 : do icall=1,NCALLS_FOR_TEST
1255 : 15 : ifft = empty_cache(CACHE_KBSIZE)
1256 : : call rho_tw_g(nspinor1,osc_npw,nfft,ndat,Ftest%ngfft,map2sphere,use_padfft,igfftg0,gbound,&
1257 : : wfn1,itim1,ktabr1,ktabp1,spinrot1,&
1258 : : wfn2,itim2,ktabr2,ktabp2,spinrot2,&
1259 : 15 : dim_rtwg1,rhotwg)
1260 : : ! Store results at the first call.
1261 [ + + + - : 36180 : if (icall==1) results = rhotwg
- + - - +
+ ]
1262 : : end do
1263 : :
1264 : 3 : call cwtime(cpu_time, wall_time, gflops, "stop")
1265 : : call Ftprof%init(test_name,Ftest%nthreads,NCALLS_FOR_TEST,Ftest%ndat,ftest%gpu_option, &
1266 : 3 : cpu_time,wall_time,gflops,results=results)
1267 : :
1268 [ - + ]: 3 : ABI_FREE(ktabr1)
1269 [ - + ]: 3 : ABI_FREE(ktabr2)
1270 [ - + ]: 3 : ABI_FREE(igfftg0)
1271 [ - + ]: 3 : ABI_FREE(gbound)
1272 [ - + ]: 3 : ABI_FREE(rhotwg)
1273 [ - + ]: 3 : ABI_FREE(wfn1)
1274 [ - + ]: 3 : ABI_FREE(wfn2)
1275 [ - + ]: 3 : ABI_FREE(results)
1276 : 3 : call destroy_mpi_enreg(MPI_enreg_seq)
1277 : :
1278 [ - + - + : 12 : end subroutine time_rhotwg
- + - + -
+ - + - +
- + - + -
+ - + - +
- + ]
1279 : : !!***
1280 : :
1281 : : !----------------------------------------------------------------------
1282 : :
1283 : : !!****f* m_FFT_prof/time_fftu
1284 : : !! NAME
1285 : : !! time_fftu
1286 : : !!
1287 : : !! FUNCTION
1288 : : !! Profiling of the fftu routines.
1289 : : !!
1290 : : !! INPUTS
1291 : : !!
1292 : : !! OUTPUT
1293 : : !!
1294 : : !! SOURCE
1295 : :
1296 : 6 : subroutine time_fftu(Ftest, isign, header, Ftprof)
1297 : :
1298 : : !Arguments -----------------------------------
1299 : : class(FFT_test_t),intent(inout) :: Ftest
1300 : : integer,intent(in) :: isign
1301 : : character(len=500),intent(out) :: header
1302 : : class(FFT_prof_t),intent(out) :: Ftprof
1303 : :
1304 : : !Local variables-------------------------------
1305 : : !scalars
1306 : : integer,parameter :: nspinor1=1
1307 : : integer :: icall,i1,i2,i3,n1,n2,n3,ifft,npw_k,ndat,dat,nfft,cnt,ipw,padat,istwf_k
1308 : : !integer :: n4,n5,n6,n456,idx
1309 : : real(dp) :: cpu_time,wall_time,gflops,gsq,g0dotr
1310 : : logical :: not_implemented
1311 : : !character(len=500) :: msg
1312 : : character(len=TNAME_LEN) :: test_name
1313 : : !arrays
1314 : : integer,parameter :: g0(3) = [1,-2,1]
1315 : : integer :: gg(3)
1316 : 6 : integer,allocatable :: kg_k(:,:),gbound(:,:)
1317 [ + - ]: 6 : complex(dp),allocatable :: ug(:),results(:),ur(:)
1318 : : ! *********************************************************************
1319 : :
1320 : 6 : test_name = Ftest%get_name()
1321 : :
1322 : 6 : n1=Ftest%ngfft(1); n2=Ftest%ngfft(2); n3=Ftest%ngfft(3)
1323 : : !n4=Ftest%ngfft(4); n5=Ftest%ngfft(5); n6=Ftest%ngfft(6)
1324 : :
1325 : 6 : nfft = n1*n2*n3
1326 : : !n456 = n4*n5*n6
1327 : 6 : ndat = Ftest%ndat
1328 : :
1329 : 6 : write(header,'(2(a,i2))')" fftu with isign ",isign,", ndat ",ndat
1330 : :
1331 : : ! TODO: zero-pad not available with SG2001 routines.
1332 : 6 : not_implemented = (Ftest%ngfft(7) == 412)
1333 : :
1334 [ + + + + ]: 6 : if (Ftest%available==0.or.not_implemented) then
1335 : 4 : call Ftprof%init(test_name,0,0,0,0,zero,zero,zero)
1336 : : return
1337 : : end if
1338 : :
1339 : 2 : call xomp_set_num_threads(Ftest%nthreads)
1340 : :
1341 [ - + ]: 2 : if (Ftest%ngfft(7)/100 == FFT_FFTW3) call fftw3_set_nthreads(Ftest%nthreads)
1342 : : !
1343 : 2 : istwf_k = Ftest%istwf_k
1344 : : !istwf_k = 1 ! Do not use istwf_k trick here
1345 : 2 : call get_kg(Ftest%kpoint,istwf_k,Ftest%ecut,Ftest%gmet,npw_k,kg_k)
1346 : :
1347 [ + - - + : 8 : ABI_MALLOC(gbound,(2*Ftest%mgfft+8,2))
+ - + - +
- + - - +
- + ]
1348 : 2 : call sphereboundary(gbound,istwf_k,kg_k,Ftest%mgfft,npw_k)
1349 : :
1350 [ - + + - : 6 : ABI_MALLOC(ug,(npw_k*ndat))
+ - + - -
+ - + ]
1351 [ - + + - : 6 : ABI_MALLOC(ur, (nfft*ndat))
+ - + - -
+ - + ]
1352 [ - + + - : 4 : ABI_MALLOC(results,(nfft*ndat))
- + - + ]
1353 [ + + ]: 1458002 : results=czero ! needed for R --> G since npw_k < nfft
1354 : :
1355 [ + + ]: 2 : if (isign==1) then
1356 [ + + ]: 34169 : do cnt=0,(npw_k * ndat) - 1
1357 : 34168 : ipw = 1 + MOD(cnt, npw_k)
1358 [ + + ]: 136672 : gg = kg_k(:,ipw)
1359 [ + + + + : 649192 : gsq = two_pi**2 * DOT_PRODUCT(gg,MATMUL(Ftest%gmet,gg))
+ + + + ]
1360 : 34169 : ug(cnt+1) = DCMPLX(EXP(-gsq), zero)
1361 : : end do
1362 : : !
1363 : : ! Replicate input data
1364 [ + - ]: 1 : do dat=2,ndat
1365 : 0 : padat = (dat-1) * npw_k
1366 [ - - ]: 1 : do ipw=1,npw_k
1367 : 0 : ug(ipw+padat) = DBLE(dat) * ug(ipw)
1368 : : end do
1369 : : end do
1370 : :
1371 [ + - ]: 1 : else if (isign==-1) then
1372 : :
1373 [ + + ]: 91 : do i3=0,n3-1
1374 [ + + ]: 8191 : do i2=0,n2-1
1375 [ + + ]: 737190 : do i1=0,n1-1
1376 : : g0dotr= two_pi*( g0(1)*(i1/DBLE(n1)) &
1377 : : +g0(2)*(i2/DBLE(n2)) &
1378 : 729000 : +g0(3)*(i3/DBLE(n3)) )
1379 : 729000 : ifft = 1 + i1 + i2*n1 + i3*n2*n3
1380 : 737100 : ur(ifft)=DCMPLX(DCOS(g0dotr),DSIN(g0dotr))
1381 : : end do
1382 : : end do
1383 : : end do
1384 : : !
1385 : : ! Replicate input data
1386 [ + - ]: 1 : do dat=2,ndat
1387 : 0 : padat = (dat-1)*nfft
1388 [ - - ]: 1 : do ifft=1,nfft
1389 : 0 : ur(ifft+padat) = DBLE(dat) * ur(ifft)
1390 : : end do
1391 : : end do
1392 : :
1393 : : else
1394 : 0 : ABI_ERROR(sjoin("Wrong isign:", itoa(isign)))
1395 : : end if
1396 : :
1397 : 2 : call cwtime(cpu_time, wall_time, gflops, "start")
1398 : :
1399 [ + + ]: 12 : do icall=1,NCALLS_FOR_TEST
1400 : 10 : ifft = empty_cache(CACHE_KBSIZE)
1401 : :
1402 : : !call fftpad(ug,Ftest%ngfft,n1,n2,n3,n4,n5,n6,ndat,Ftest%mgfft,isign,gbound)
1403 [ + + ]: 12 : if (isign == +1) then
1404 : 5 : call fft_ug(npw_k,nfft,nspinor1,ndat,Ftest%mgfft,Ftest%ngfft,istwf_k,kg_k,gbound,ug,ur)
1405 : : ! Store results at the first call.
1406 [ + + ]: 5 : if (icall == 1) call xcopy(nfft*ndat,ur,1,results,1)
1407 : :
1408 : : else
1409 : 5 : call fft_ur(npw_k,nfft,nspinor1,ndat,Ftest%mgfft,Ftest%ngfft,istwf_k,kg_k,gbound,ur,ug)
1410 : : ! Store results at the first call.
1411 [ + + ]: 5 : if (icall==1) call xcopy(npw_k*ndat,ug,1,results,1)
1412 : : end if
1413 : : !if (isign==-1) then
1414 : : ! write(Ftest%ngfft(7),*)"ngfft, isign ",Ftest%ngfft(7),isign
1415 : : ! do idx =1,n4*n5*n6*ndat; write(Ftest%ngfft(7),*)idx,results(idx); end do
1416 : : !end if
1417 : : end do
1418 : :
1419 : 2 : call cwtime(cpu_time, wall_time, gflops, "stop")
1420 : : call Ftprof%init(test_name,Ftest%nthreads,NCALLS_FOR_TEST,ndat,ftest%gpu_option, &
1421 : 2 : cpu_time,wall_time,gflops,results=results)
1422 : :
1423 [ - + ]: 2 : ABI_FREE(kg_k)
1424 [ - + ]: 2 : ABI_FREE(gbound)
1425 [ - + ]: 2 : ABI_FREE(ug)
1426 [ - + ]: 2 : ABI_FREE(ur)
1427 [ - + ]: 2 : ABI_FREE(results)
1428 : :
1429 : 4 : end subroutine time_fftu
1430 : : !!***
1431 : :
1432 : : !----------------------------------------------------------------------
1433 : :
1434 : : !!****f* m_FFT_prof/prof_fourdp
1435 : : !! NAME
1436 : : !! prof_fourdp
1437 : : !!
1438 : : !! FUNCTION
1439 : : !! Profile fourdp
1440 : : !!
1441 : : !! INPUTS
1442 : : !!
1443 : : !! OUTPUT
1444 : : !!
1445 : : !! SOURCE
1446 : :
1447 [ # # ]: 0 : subroutine prof_fourdp(fft_setups, isign, cplex, necut, ecut_arth, boxcutmin, rprimd, nsym, symrel, MPI_enreg_in)
1448 : :
1449 : : !Arguments -----------------------------------
1450 : : !scalars
1451 : : integer,intent(in) :: nsym,isign,cplex,necut
1452 : : real(dp),intent(in) :: boxcutmin
1453 : : type(MPI_type),intent(in) :: MPI_enreg_in
1454 : : !arrays
1455 : : integer,intent(in) :: fft_setups(:,:),symrel(3,3,nsym)
1456 : : real(dp),intent(in) :: ecut_arth(2)
1457 : : real(dp),intent(in) :: rprimd(3,3)
1458 : :
1459 : : !Local variables-------------------------------
1460 : : !scalars
1461 : : integer :: iec,nsetups,set,funt
1462 [ # # # # ]: 0 : type(FFT_test_t) :: Ftest
1463 : 0 : type(FFT_prof_t) :: Ftprof
1464 : : character(len=500) :: msg,frm,header
1465 : : character(len=fnlen) :: fname
1466 : : !arrays
1467 : 0 : integer :: ngfft_ecut(18,necut)
1468 : : real(dp),parameter :: k_gamma(3)=zero
1469 : 0 : real(dp) :: ecut_list(necut)
1470 : 0 : real(dp),allocatable :: prof_res(:,:,:)
1471 : : ! *********************************************************************
1472 : :
1473 : 0 : nsetups = size(fft_setups, dim=2)
1474 : 0 : ecut_list = arth(ecut_arth(1), ecut_arth(2), necut)
1475 : :
1476 : : ! Open file and write header with info.
1477 : 0 : write(fname,'(2(a,i1))')"PROF_fourdp_cplex",cplex,"_isign",isign
1478 [ # # ]: 0 : if (open_file(fname, msg, newunit=funt) /= 0) then
1479 : 0 : ABI_ERROR(msg)
1480 : : end if
1481 : :
1482 : 0 : write(msg,'(2(a,i0))')"Benchmark: routine = fourdp, cplex =",cplex,", isign=",isign
1483 : 0 : write(std_out,'(a)')" Running "//TRIM(msg)
1484 : :
1485 : 0 : write(funt,'(a)')"# "//TRIM(msg)
1486 [ # # ]: 0 : do set=1,nsetups
1487 : 0 : write(funt,'(a, 6(a,i0))') "#",&
1488 : 0 : " fftalg = " ,fft_setups(1,set), &
1489 : 0 : ", fftcache = " ,fft_setups(2,set), &
1490 : 0 : ", ndat = " ,fft_setups(3,set), &
1491 : 0 : ", nthreads = " ,fft_setups(4,set), &
1492 : 0 : ", available = ",fft_setups(5,set), &
1493 : 0 : ", gpu_option = ",fft_setups(6,set)
1494 : : end do
1495 : :
1496 [ # # # # : 0 : ABI_MALLOC(prof_res,(2,necut,nsetups))
# # # # #
# # # # #
# # ]
1497 : :
1498 [ # # ]: 0 : do set=1,nsetups
1499 [ # # ]: 0 : do iec=1,necut
1500 [ # # # # : 0 : call Ftest%init(fft_setups(:,set),k_gamma,ecut_list(iec),boxcutmin,rprimd,nsym,symrel,MPI_enreg_in)
# # # # ]
1501 : 0 : call Ftest%time_fourdp(isign, cplex, header, Ftprof)
1502 : :
1503 : 0 : prof_res(1,iec,set) = Ftprof%cpu_time /Ftprof%ncalls
1504 : 0 : prof_res(2,iec,set) = Ftprof%wall_time/Ftprof%ncalls
1505 : :
1506 : : ! Save FFT divisions.
1507 [ # # # # ]: 0 : if (set == 1) ngfft_ecut(:,iec) = Ftest%ngfft
1508 : :
1509 : 0 : call Ftprof%free()
1510 : 0 : call Ftest%free()
1511 : : end do
1512 : : end do
1513 : :
1514 : : ! Write the wall-time as a function of ecut.
1515 : 0 : write(frm,*)"(f7.1,3i4,",nsetups,"(f7.4))"
1516 [ # # ]: 0 : do iec=1,necut
1517 : 0 : write(funt,frm) ecut_list(iec),ngfft_ecut(4:6,iec),prof_res(2,iec,:)
1518 : : end do
1519 : :
1520 : 0 : close(funt)
1521 [ # # ]: 0 : ABI_FREE(prof_res)
1522 : :
1523 [ # # # # : 0 : end subroutine prof_fourdp
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
1524 : : !!***
1525 : :
1526 : : !----------------------------------------------------------------------
1527 : :
1528 : : !!****f* m_FFT_prof/prof_fourwf
1529 : : !! NAME
1530 : : !! prof_fourwf
1531 : : !!
1532 : : !! FUNCTION
1533 : : !! profile fourwf
1534 : : !!
1535 : : !! INPUTS
1536 : : !!
1537 : : !! OUTPUT
1538 : : !!
1539 : : !! SOURCE
1540 : :
1541 [ # # ]: 0 : subroutine prof_fourwf(fft_setups, cplex, option, kpoint, necut, ecut_arth, &
1542 : 0 : boxcutmin, rprimd, nsym, symrel, MPI_enreg_in)
1543 : :
1544 : : !Arguments -----------------------------------
1545 : : !scalars
1546 : : integer,intent(in) :: nsym,cplex,necut,option
1547 : : real(dp),intent(in) :: boxcutmin
1548 : : type(MPI_type),intent(in) :: MPI_enreg_in
1549 : : !arrays
1550 : : integer,intent(in) :: fft_setups(:,:),symrel(3,3,nsym)
1551 : : real(dp),intent(in) :: ecut_arth(2)
1552 : : real(dp),intent(in) :: kpoint(3),rprimd(3,3)
1553 : :
1554 : : !Local variables-------------------------------
1555 : : !scalars
1556 : : integer :: iec,nsetups,set,funt,istwf_k
1557 [ # # # # ]: 0 : type(FFT_test_t) :: Ftest
1558 : 0 : type(FFT_prof_t) :: Ftprof
1559 : : character(len=500) :: msg,frm,header
1560 : : character(len=fnlen) :: fname
1561 : : !arrays
1562 : 0 : integer :: ngfft_ecut(18,necut)
1563 : 0 : real(dp) :: ecut_list(necut)
1564 : 0 : real(dp),allocatable :: prof_res(:,:,:)
1565 : : ! *********************************************************************
1566 : :
1567 : 0 : nsetups = size(fft_setups, dim=2)
1568 : 0 : ecut_list = arth(ecut_arth(1), ecut_arth(2), necut)
1569 : 0 : istwf_k = set_istwfk(kpoint)
1570 : :
1571 : : ! Open file and write header with info.
1572 : 0 : write(fname,'(3(a,i1))')"PROF_fourwf_cplex",cplex,"_option",option,"_istwfk",istwf_k
1573 [ # # ]: 0 : if (open_file(fname, msg, newunit=funt) /= 0) then
1574 : 0 : ABI_ERROR(msg)
1575 : : end if
1576 : :
1577 : 0 : write(msg,'(3(a,i1))')"Benchmark: routine = fourwf, cplex = ",cplex,", option= ",option,", istwfk= ",istwf_k
1578 : 0 : write(std_out,'(a)')" Running "//TRIM(msg)
1579 : :
1580 : 0 : write(funt,'(a)')"# "//TRIM(msg)
1581 [ # # ]: 0 : do set=1,nsetups
1582 : 0 : write(funt,'(a,6(a,i0))') "#",&
1583 : 0 : " fftalg = " ,fft_setups(1,set), &
1584 : 0 : ", fftcache = " ,fft_setups(2,set), &
1585 : 0 : ", ndat = " ,fft_setups(3,set), &
1586 : 0 : ", nthreads = " ,fft_setups(4,set), &
1587 : 0 : ", available = ",fft_setups(5,set), &
1588 : 0 : ", gpu_option = ",fft_setups(6,set)
1589 : : end do
1590 : :
1591 [ # # # # : 0 : ABI_MALLOC(prof_res,(2,necut,nsetups))
# # # # #
# # # # #
# # ]
1592 : :
1593 [ # # ]: 0 : do set=1,nsetups
1594 [ # # ]: 0 : do iec=1,necut
1595 [ # # # # : 0 : call Ftest%init(fft_setups(:,set),kpoint,ecut_list(iec),boxcutmin,rprimd,nsym,symrel,MPI_enreg_in)
# # # # ]
1596 : 0 : call Ftest%time_fourwf(cplex, option, header, Ftprof)
1597 : :
1598 : 0 : prof_res(1,iec,set) = Ftprof%cpu_time /Ftprof%ncalls
1599 : 0 : prof_res(2,iec,set) = Ftprof%wall_time/Ftprof%ncalls
1600 : :
1601 : : ! Save FFT divisions.
1602 [ # # # # ]: 0 : if (set == 1) ngfft_ecut(:,iec) = Ftest%ngfft
1603 : 0 : call Ftprof%free()
1604 : 0 : call Ftest%free()
1605 : : end do
1606 : : end do
1607 : :
1608 : : ! Write the wall-time as a function of ecut.
1609 : 0 : write(frm,*)"(f7.1,3i4,",nsetups,"(f7.4))"
1610 [ # # ]: 0 : do iec=1,necut
1611 : 0 : write(funt,frm) ecut_list(iec),ngfft_ecut(4:6,iec),prof_res(2,iec,:)
1612 : : end do
1613 : :
1614 : 0 : close(funt)
1615 [ # # ]: 0 : ABI_FREE(prof_res)
1616 : :
1617 [ # # # # : 0 : end subroutine prof_fourwf
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
1618 : : !!***
1619 : :
1620 : : !----------------------------------------------------------------------
1621 : :
1622 : : !!****f* m_FFT_prof/prof_rhotwg
1623 : : !! NAME
1624 : : !! prof_rhotwg
1625 : : !!
1626 : : !! FUNCTION
1627 : : !! profile rhotwg
1628 : : !!
1629 : : !! INPUTS
1630 : : !!
1631 : : !! OUTPUT
1632 : : !!
1633 : : !! SOURCE
1634 : :
1635 [ # # ]: 0 : subroutine prof_rhotwg(fft_setups,map2sphere,use_padfft,necut,ecut_arth,osc_ecut,boxcutmin,&
1636 : 0 : rprimd,nsym,symrel,gmet,MPI_enreg_in)
1637 : :
1638 : : !Arguments -----------------------------------
1639 : : !scalars
1640 : : integer,intent(in) :: nsym,necut,map2sphere,use_padfft
1641 : : real(dp),intent(in) :: boxcutmin,osc_ecut
1642 : : type(MPI_type),intent(in) :: MPI_enreg_in
1643 : : !arrays
1644 : : integer,intent(in) :: fft_setups(:,:),symrel(3,3,nsym)
1645 : : real(dp),intent(in) :: ecut_arth(2)
1646 : : real(dp),intent(in) :: rprimd(3,3),gmet(3,3)
1647 : :
1648 : : !Local variables-------------------------------
1649 : : !scalars
1650 : : integer :: iec,nsetups,set,funt,osc_npw
1651 [ # # # # ]: 0 : type(FFT_test_t) :: Ftest
1652 : 0 : type(FFT_prof_t) :: Ftprof
1653 : : character(len=500) :: msg,frm,header
1654 : : character(len=fnlen) :: fname
1655 : : !arrays
1656 : 0 : integer,allocatable :: osc_gvec(:,:)
1657 : 0 : integer :: ngfft_ecut(18,necut)
1658 : : real(dp),parameter :: k_gamma(3)=zero
1659 : 0 : real(dp) :: ecut_list(necut)
1660 : 0 : real(dp),allocatable :: prof_res(:,:,:)
1661 : : ! *********************************************************************
1662 : :
1663 : 0 : nsetups = size(fft_setups, dim=2)
1664 : 0 : ecut_list = arth(ecut_arth(1), ecut_arth(2), necut)
1665 : :
1666 : : ! Open file and write header with info.
1667 : 0 : write(fname,'(2(a,i1))')"PROF_rhotwg_map2sphere",map2sphere,"_use_padfft",use_padfft
1668 [ # # ]: 0 : if (open_file(fname, msg, newunit=funt) /= 0) then
1669 : 0 : ABI_ERROR(msg)
1670 : : end if
1671 : :
1672 : : write(msg,'(2(a,i0),a,f5.1)') &
1673 : 0 : "Benchmark: routine = rho_tw_g, map2sphere = ",map2sphere,", use_padfft = ",use_padfft,", osc_ecut = ",osc_ecut
1674 : 0 : write(std_out,'(a)')" Running "//TRIM(msg)
1675 : :
1676 : 0 : write(funt,'(a)')"# "//TRIM(msg)
1677 [ # # ]: 0 : do set=1,nsetups
1678 : 0 : write(funt,'(a,6(a,i0))') "#",&
1679 : 0 : " fftalg = " ,fft_setups(1,set),&
1680 : 0 : ", fftcache = " ,fft_setups(2,set),&
1681 : 0 : ", ndat = " ,fft_setups(3,set),&
1682 : 0 : ", nthreads = " ,fft_setups(4,set),&
1683 : 0 : ", available = ",fft_setups(5,set),&
1684 : 0 : ", gpu_option = ",fft_setups(6,set)
1685 : : end do
1686 : :
1687 : 0 : call get_kg([zero,zero,zero],1,osc_ecut,gmet,osc_npw,osc_gvec)
1688 : : ! TODO should reorder by shells to be consistent with the GW part!
1689 : : ! Moreover I guess this ordering is more efficient when we have
1690 : : ! to map the box to the G-sphere!
1691 : :
1692 [ # # # # : 0 : ABI_MALLOC(prof_res,(2,necut,nsetups))
# # # # #
# # # # #
# # ]
1693 : :
1694 [ # # ]: 0 : do set=1,nsetups
1695 [ # # ]: 0 : do iec=1,necut
1696 [ # # # # : 0 : call Ftest%init(fft_setups(:,set),k_gamma,ecut_list(iec),boxcutmin,rprimd,nsym,symrel,MPI_enreg_in)
# # # # ]
1697 : :
1698 : 0 : call Ftest%time_rhotwg(map2sphere,use_padfft,osc_npw,osc_gvec,header,Ftprof)
1699 : :
1700 : 0 : prof_res(1,iec,set) = Ftprof%cpu_time /Ftprof%ncalls
1701 : 0 : prof_res(2,iec,set) = Ftprof%wall_time/Ftprof%ncalls
1702 : : ! Save FFT divisions.
1703 [ # # # # ]: 0 : if (set==1) ngfft_ecut(:,iec) = Ftest%ngfft
1704 : :
1705 : 0 : call Ftprof%free()
1706 : 0 : call Ftest%free()
1707 : : end do
1708 : : end do
1709 : :
1710 : : ! Write the wall-time as a function of ecut.
1711 : 0 : write(frm,*)"(f7.1,3i4,",nsetups,"(f7.4))"
1712 [ # # ]: 0 : do iec=1,necut
1713 : 0 : write(funt,frm) ecut_list(iec),ngfft_ecut(4:6,iec),prof_res(2,iec,:)
1714 : : end do
1715 : :
1716 : 0 : close(funt)
1717 [ # # ]: 0 : ABI_FREE(prof_res)
1718 [ # # ]: 0 : ABI_FREE(osc_gvec)
1719 : :
1720 [ # # # # : 0 : end subroutine prof_rhotwg
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
1721 : : !!***
1722 : :
1723 : : !----------------------------------------------------------------------
1724 : :
1725 : : !!****f* m_FFT_prof/empty_cache
1726 : : !! NAME
1727 : : !! empty_cache
1728 : : !!
1729 : : !! FUNCTION
1730 : : !! Empty the memory cache
1731 : : !!
1732 : : !! INPUTS
1733 : : !!
1734 : : !! OUTPUT
1735 : : !!
1736 : : !! SOURCE
1737 : :
1738 : 1445 : integer function empty_cache(kbsize) result(fake)
1739 : :
1740 : : !Arguments -----------------------------------
1741 : : integer,intent(in) :: kbsize
1742 : :
1743 : : !Local variables-------------------------------
1744 : : integer :: sz
1745 : 1445 : real(dp),allocatable :: chunk(:)
1746 : : ! *********************************************************************
1747 : :
1748 : 1445 : fake = 0
1749 [ - + ]: 1445 : if (kbsize <= 0) RETURN
1750 : :
1751 : 0 : sz = int((100._dp * kbsize) / dp)
1752 : :
1753 [ # # # # : 0 : ABI_MALLOC(chunk,(sz))
# # # # #
# # # ]
1754 : 0 : call random_number(chunk)
1755 [ # # ]: 0 : fake = int(SUM(chunk)) ! Need a result, otherwise smart compilers may skip the call.
1756 [ # # ]: 0 : ABI_FREE(chunk)
1757 : :
1758 [ - + ]: 1445 : end function empty_cache
1759 : : !!***
1760 : :
1761 : : !----------------------------------------------------------------------
1762 : :
1763 [ - + - - : 1612 : end module m_FFT_prof
+ + - + +
- - + # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
1764 : : !!***
|