Line data Source code
1 : !!****p* ABINIT/fftprof
2 : !! NAME
3 : !! fftprof
4 : !!
5 : !! FUNCTION
6 : !! Utility for profiling the FFT libraries supported by ABINIT.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2004-2026 ABINIT group (MG)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! OUTPUT
15 : !! Timing analysis of the different FFT libraries and algorithms.
16 : !!
17 : !! NOTES
18 : !! Point-group symmetries are not taken into account in getng during the generation
19 : !! of the FFT mesh. Therefore the FFT mesh might differ from the one
20 : !! found by abinit for the same cutoff and Bravais lattice (actually it might be smaller).
21 : !!
22 : !! Description of the input file (Fortran NAMELIST):
23 : !!
24 : !! &CONTROL
25 : !! tasks = string specifying the tasks to perform i.e. the routines that should be tested or profiled.
26 : !! allowed values:
27 : !! fourdp --> Test FFT transforms of density and potentials on the full box.
28 : !! fourwf --> Test FFT transforms of wavefunctions using the zero-padded algorithm.
29 : !! gw_fft --> Test the FFT transforms used in the GW code.
30 : !! all --> Test all FFT routines (DEFAULT)
31 : !! fftalgs = list of fftalg values (used to select the FFT libraries to use, see abinit doc for more info)
32 : !! gpu_options = for each fftalg in fftalgs, it is set to 0 if the GPU version doesnt have
33 : !! to be used, or to the value selecting the GPU implementation (see defs_basis.F90)
34 : !! ncalls = integer defining the number of calls for each tests. The final Wall time and CPU time
35 : !! are computed by averaging the final results over ncalls executions.
36 : !! max_nthreads = Maximum number of threads (DEFAULT 1, meaningful only if the code
37 : !! uses threaded external libraries or OpenMP parallelization)
38 : !! ndat = integer specifying how many FFT transforms should be executed for each call to the FFT routine
39 : !! (same meaning as the ndat input variable passed to fourwf)
40 : !! necut = Used if tasks = "bench". Specifies the number of cutoff energies to profile (see also ecut_arth)
41 : !! ecut_arth = Used if tasks = "bench". Used to generate an arithmetic progression of cutoff energies
42 : !! whose starting value is ecut_arth(1) and whose step is ecut_arth(2)
43 : !!
44 : !! &SYSTEM
45 : !! ecut = cutoff energy for wavefunctions (real, Hartree units)
46 : !! rprimd = Direct lattice vectors in Bohr. (3,3) matrix in Fortran column-major order
47 : !! kpoint = real(3) vector specifying the reduced coordinates of the k-point of the wavefunction (used if tasks = "fourwf").
48 : !! The value of the k-point defines the storage scheme (istwfk) of the u(G) coefficients and therefore
49 : !! the FFT algorithm used to perform the transform u(G) <--> u(R) in fourwf.
50 : !! osc_ecut = cutoff energy (Hartree) for the oscillator matrix elements computed in the GW code
51 : !! Corresponds to the input variables (ecuteps, ecutsigx) used in the main code.
52 : !! nsym =Number of symmetry operations (DEFAULT 1)
53 : !! symrel(3,3,nsym) = Symmetry operation in real space used to select
54 : !! the FFT mesh in the routine getng (default: Identity matrix)
55 : !! NOTE that the real tnons is not taken into account anyhow: tnons is set to zero.
56 : !!
57 : !! SOURCE
58 :
59 : #if defined HAVE_CONFIG_H
60 : #include "config.h"
61 : #endif
62 :
63 : #include "abi_common.h"
64 :
65 38 : program fftprof
66 :
67 38 : use defs_basis
68 : use m_xmpi
69 : use m_xomp
70 : use m_errors
71 : use m_abicore
72 : use m_dfti
73 : use m_abi_linalg
74 : #ifdef HAVE_GPU_CUDA
75 : use m_gpu_toolbox
76 : use m_manage_cuda
77 : #endif
78 :
79 : use defs_abitypes, only : MPI_type
80 : use m_build_info, only : abinit_version
81 : use m_fstrings, only : lower
82 : use m_specialmsg, only : specialmsg_getcount, herald
83 : use m_argparse, only : get_arg !, get_arg_list, get_start_step_num
84 : use m_io_tools, only : flush_unit
85 : use m_geometry, only : metric
86 : use m_fftcore, only : get_cache_kb, get_kg, fftalg_isavailable, fftalg_has_mpi, getng, fftcore_set_mixprec
87 : use m_fft, only : fft_use_lib_threads, fftbox_utests, fftu_utests, fftbox_mpi_utests, fftu_mpi_utests, uplan_utests
88 : use m_fftw3, only : fftw3_init_threads
89 : use m_fft_prof, only : fft_test_t, fft_prof_t, fft_tests_free, fftprof_ncalls_per_test, fftprofs_free, &
90 : fftprofs_print, prof_fourdp, prof_fourwf, prof_rhotwg
91 : use m_mpinfo, only : destroy_mpi_enreg, initmpi_seq
92 :
93 : implicit none
94 :
95 : !Arguments -----------------------------------
96 : !scalars
97 : integer,parameter :: MAX_NFFTALGS = 50, MAX_NSYM = 48, wfoptalg = 4
98 : integer,parameter :: paral_kgb0 = 0, me_fft0 = 0, nproc_fft1 = 1, master = 0, np_slk1 = 1, use_slk0 = 0
99 : integer :: ii,fftcache,it,cplex,ntests,option_fourwf,osc_npw, linalg_max_size
100 : integer :: map2sphere,use_padfft,isign,nthreads,comm,nprocs,my_rank
101 : integer :: iset,iall,inplace,nsets,avail,ith,idx,ut_nfft,ut_mgfft
102 : integer :: nfftalgs,alg,fftalg,fftalga,fftalgc,nfailed,ierr,paral_kgb,abimem_level
103 : character(len=24) :: codename
104 : character(len=500) :: header,msg
105 : real(dp),parameter :: boxcutmin2 = two
106 : real(dp) :: ucvol, abimem_limit_mb
107 : logical :: test_fourdp,test_fourwf,test_gw,do_seq_bench,do_seq_utests
108 : logical :: iam_master,do_mpi_utests !,do_mpi_bench,
109 38 : type(MPI_type) :: MPI_enreg
110 : !arrays
111 : integer :: ut_ngfft(18)
112 : #ifdef HAVE_GPU_CUDA
113 : integer :: gpu_devices(12)
114 : #endif
115 : real(dp),parameter :: gamma_point(3) = zero
116 : real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3)
117 38 : type(FFT_test_t),allocatable :: Ftest(:)
118 38 : type(FFT_prof_t),allocatable :: Ftprof(:)
119 38 : integer,allocatable :: osc_gvec(:,:), fft_setups(:,:),fourwf_params(:,:)
120 : ! ========== INPUT FILE ==============
121 : integer :: ncalls = 10, max_nthreads = 1, ndat = 1, necut = 0, nsym = 1
122 : integer :: mixprec = 0, gpu_option = 0, init_gpu_flavor
123 : character(len=500) :: tasks="all"
124 : integer :: fftalgs(MAX_NFFTALGS) = 0, gpu_options(MAX_NFFTALGS) = 0
125 : integer :: symrel(3,3,MAX_NSYM) = 0
126 : real(dp),parameter :: k0(3) = zero
127 : real(dp) :: ecut = 30, osc_ecut = 3
128 : real(dp) :: ecut_arth(2) = zero, rprimd(3,3)
129 : real(dp) :: kpoint(3) = [0.1,0.2,0.3], tnons(3,MAX_NSYM) = zero
130 : logical :: use_lib_threads = .FALSE.
131 : namelist /CONTROL/ tasks, ncalls, max_nthreads, ndat, fftalgs, gpu_options, &
132 : necut, ecut_arth, use_lib_threads, mixprec
133 : namelist /SYSTEM/ ecut, rprimd, kpoint, osc_ecut, nsym, symrel
134 : ! *************************************************************************
135 :
136 : ! Change communicator for I/O (mandatory!)
137 38 : call abi_io_redirect(new_io_comm=xmpi_world)
138 :
139 38 : call xmpi_init()
140 38 : comm = xmpi_world
141 38 : my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
142 38 : iam_master = (my_rank == master)
143 :
144 : ! Initialize memory profiling if it is activated
145 : ! if a full abimem.mocc report is desired, set the argument of abimem_init to "2" instead of "0"
146 : ! note that abimem.mocc files can easily be multiple GB in size so don't use this option normally
147 38 : ABI_CHECK(get_arg("abimem-level", abimem_level, msg, default=0) == 0, msg)
148 38 : ABI_CHECK(get_arg("abimem-limit-mb", abimem_limit_mb, msg, default=20.0_dp) == 0, msg)
149 : #ifdef HAVE_MEM_PROFILING
150 : call abimem_init(abimem_level, limit_mb=abimem_limit_mb)
151 : #endif
152 :
153 38 : if (iam_master) then
154 : ! Print header and read input file.
155 38 : codename='FFTPROF'//REPEAT(' ',17)
156 38 : call herald(codename,abinit_version,std_out)
157 :
158 38 : write(std_out,'(a)')" Tool for profiling and testing the FFT libraries used in ABINIT."
159 38 : write(std_out,'(a)')" Allowed options are: "
160 38 : write(std_out,'(a)')" fourdp --> Test FFT transforms of density and potentials on the full box."
161 38 : write(std_out,'(a)')" fourwf --> Test FFT transforms of wavefunctions using the zero-pad algorithm."
162 38 : write(std_out,'(a)')" gw_fft --> Test the FFT transforms used in the GW code."
163 38 : write(std_out,'(a)')" all --> Test all FFT routines."
164 : !write(std_out,'(a)')" seq-utests --> Units tests for sequential FFTs."
165 : !write(std_out,'(a)')" mpi-utests --> Units tests for MPI FFTs."
166 : !write(std_out,'(a)')" seq-bench --> Benchmark mode for sequential FFTs."
167 : !write(std_out,'(a)')" mpi-bench --> Benchmark mode for MPI FFTs."
168 38 : write(std_out,'(a)')" "
169 :
170 : !Read input file
171 38 : read(std_in, NML=CONTROL)
172 38 : read(std_in, NML=SYSTEM)
173 : !write(std_out, NML=CONTROL)
174 : !write(std_out, NML=SYSTEM)
175 38 : call lower(tasks)
176 : end if
177 :
178 : ! Broadcast variables.
179 38 : if (nprocs > 1) then
180 : ! CONTROL
181 0 : call xmpi_bcast(tasks,master,comm,ierr)
182 0 : call xmpi_bcast(ncalls,master,comm,ierr)
183 0 : call xmpi_bcast(max_nthreads,master,comm,ierr)
184 0 : call xmpi_bcast(ndat,master,comm,ierr)
185 0 : call xmpi_bcast(fftalgs,master,comm,ierr)
186 0 : call xmpi_bcast(gpu_options,master,comm,ierr)
187 0 : call xmpi_bcast(necut,master,comm,ierr)
188 0 : call xmpi_bcast(ecut_arth,master,comm,ierr)
189 0 : call xmpi_bcast(use_lib_threads,master,comm,ierr)
190 0 : call xmpi_bcast(mixprec,master,comm,ierr)
191 : ! SYSTEM
192 0 : call xmpi_bcast(ecut,master,comm,ierr)
193 0 : call xmpi_bcast(rprimd,master,comm,ierr)
194 0 : call xmpi_bcast(kpoint,master,comm,ierr)
195 0 : call xmpi_bcast(osc_ecut,master,comm,ierr)
196 0 : call xmpi_bcast(nsym,master,comm,ierr)
197 0 : call xmpi_bcast(symrel,master,comm,ierr)
198 : end if
199 :
200 : ! Set precision for FFT libs.
201 38 : ii = fftcore_set_mixprec(mixprec)
202 :
203 : ! replace "+" with white spaces
204 282 : do ii=1,LEN_TRIM(tasks)
205 282 : if (tasks(ii:ii) == "+") tasks(ii:ii) = " "
206 : end do
207 : !%call str_replace_chars(tasks,"+"," ")
208 38 : tasks = " "//TRIM(tasks)//""
209 :
210 38 : iall=INDEX (tasks,"all")
211 38 : test_fourdp = (iall>0 .or. INDEX(tasks," fourdp")>0 )
212 38 : test_fourwf = (iall>0 .or. INDEX(tasks," fourwf")>0 )
213 38 : test_gw = (iall>0 .or. INDEX(tasks," gw_fft")>0 )
214 :
215 38 : do_seq_utests = INDEX(tasks," utests") >0
216 38 : do_seq_bench = INDEX(tasks," bench") >0
217 38 : do_mpi_utests = INDEX(tasks," mpi-utests")>0
218 : !do_mpi_bench = INDEX(tasks," mpi-bench")>0
219 :
220 : #ifdef HAVE_FFTW3_THREADS
221 : call fftw3_init_threads()
222 : #endif
223 :
224 : #ifndef HAVE_OPENMP
225 38 : ABI_CHECK(max_nthreads <= 1, "nthreads>1 but OMP support is not enabled!")
226 : #endif
227 38 : if (max_nthreads>1 .and. iam_master) call xomp_show_info(std_out)
228 :
229 38 : call fft_use_lib_threads(use_lib_threads)
230 : !write(std_out,*)"use_lib_threads: ",use_lib_threads
231 :
232 1938 : init_gpu_flavor = maxval(gpu_options)
233 : #if defined HAVE_GPU_CUDA
234 : if (init_gpu_flavor /= ABI_GPU_DISABLED) then
235 : gpu_devices(:)=-1
236 : call setdevice_cuda(gpu_devices, init_gpu_flavor)
237 : ABI_CHECK(init_gpu_flavor /= ABI_GPU_DISABLED, "Cannot find any free GPU device!")
238 : ! Cublas initialization
239 : call gpu_linalg_init()
240 : end if
241 : #endif
242 :
243 : ! linalg initialisation (required by subdiago)
244 38 : linalg_max_size = 1
245 : !call abi_linalg_init(linalg_max_size, RUNL_GSTATE, wfoptalg, paral_kgb0,&
246 : ! init_gpu_flavor, use_slk0, np_slk1, xmpi_comm_self)
247 :
248 38 : if (do_mpi_utests) then
249 : ! Execute unit tests for MPI FFTs and terminate execution.
250 4 : call wrtout(std_out, "=== MPI FFT Unit Tests ===")
251 :
252 : ! List the FFT libraries that will be tested.
253 : ! Goedecker FFTs are always available, other libs are optional.
254 204 : nfftalgs = COUNT(fftalgs /= 0)
255 4 : ABI_CHECK(nfftalgs > 0, "fftalgs must be specified")
256 :
257 4 : nfailed = 0; nthreads = 0
258 12 : do ii=1,nfftalgs
259 8 : fftalg = fftalgs(ii); gpu_option = gpu_options(ii)
260 20 : do paral_kgb=1,1
261 : write(msg,"(5(a,i0))")&
262 8 : "MPI fftu_utests with fftalg = ",fftalg,", paral_kgb = ",paral_kgb," ndat = ",ndat,", nthreads = ",nthreads
263 8 : call wrtout(std_out, msg)
264 16 : nfailed = nfailed + fftu_mpi_utests(fftalg,ecut,rprimd,ndat,nthreads,comm,paral_kgb)
265 : end do
266 : end do
267 :
268 4 : nfailed = 0; nthreads = 0
269 12 : do ii=1,nfftalgs
270 8 : fftalg = fftalgs(ii); gpu_option = gpu_options(ii)
271 28 : do cplex=1,2
272 : write(msg,"(4(a,i0))")&
273 16 : "MPI fftbox_utests with fftalg = ",fftalg,", cplex = ",cplex," ndat = ",ndat,", nthreads = ",nthreads
274 16 : call wrtout(std_out, msg)
275 24 : nfailed = nfailed + fftbox_mpi_utests(fftalg=fftalg,cplex=cplex,ndat=ndat,nthreads=nthreads,comm_fft=comm)
276 : end do
277 : end do
278 :
279 4 : write(msg,'(a,i0)')"Total number of failed tests = ",nfailed
280 4 : call wrtout(std_out, msg)
281 4 : goto 100 ! Jump to xmpi_end
282 : end if
283 :
284 34 : call initmpi_seq(MPI_enreg)
285 34 : call metric(gmet,gprimd,std_out,rmet,rprimd,ucvol)
286 :
287 : ! symmetries (if given) are used for defining the FFT mesh.
288 21250 : if (nsym==1 .and. ALL(symrel==0)) then
289 442 : symrel(:,:,1) = RESHAPE([1,0,0,0,1,0,0,0,1], [3,3])
290 : end if
291 :
292 : ! Set the number of calls for test.
293 34 : ncalls=ABS(ncalls); if (ncalls==0) ncalls=10
294 34 : call fftprof_ncalls_per_test(ncalls)
295 :
296 : ! List the FFT libraries that will be tested.
297 : ! Goedecker FFTs are always available, other libs are optional.
298 1734 : nfftalgs = count(fftalgs /= 0)
299 34 : ABI_CHECK(nfftalgs > 0, "fftalgs must be specified")
300 :
301 34 : ntests = max_nthreads * nfftalgs
302 :
303 : ! First dimension contains [fftalg, fftcache, ndat, nthreads, available, gpu_option]
304 34 : ABI_MALLOC(fft_setups, (6, ntests))
305 :
306 : ! Default Goedecker library.
307 34 : idx=0
308 230 : do alg=1,nfftalgs
309 196 : fftalg = fftalgs(alg); gpu_option = gpu_options(alg)
310 196 : fftalga = fftalg/100; fftalgc = mod(fftalg, 10)
311 196 : avail = merge(1, 0, fftalg_isavailable(fftalg))
312 : !fftcache is machine-dependent.
313 196 : fftcache = get_cache_kb()
314 426 : do ith=1,max_nthreads
315 196 : idx = idx + 1
316 1568 : fft_setups(:,idx) = [fftalg, fftcache, ndat, ith, avail, gpu_option]
317 : end do
318 : end do
319 :
320 : ! Init Ftest objects.
321 944 : ABI_MALLOC(Ftest, (ntests))
322 230 : ABI_MALLOC(Ftprof, (ntests))
323 :
324 230 : do it=1,ntests
325 196 : call Ftest(it)%init(fft_setups(:,it), kpoint, ecut, boxcutmin2, rprimd, nsym, symrel, MPI_enreg)
326 : ! Ftest%results is allocated using nfftot and the consistency btw libs is tested assuming an equal number of FFT-points.
327 784 : if ( ANY(Ftest(it)%ngfft(1:3) /= Ftest(1)%ngfft(1:3)) ) then
328 0 : ABI_ERROR("Consistency check assumes equal FFT meshes. Cannot continue")
329 : end if
330 230 : if (it == 1) then
331 34 : call Ftest(it)%print() !,header)
332 162 : else if (fft_setups(1,it) /= fft_setups(1,it-1)) then
333 162 : call Ftest(it)%print() !,header)
334 : end if
335 : end do
336 :
337 : ! =======================
338 : ! ==== fourdp timing ====
339 : ! =======================
340 34 : if (test_fourdp) then
341 6 : do isign=-1,1,2
342 14 : do cplex=1,2
343 40 : do it=1,ntests
344 40 : call Ftest(it)%time_fourdp(isign, cplex, header, Ftprof(it))
345 : end do
346 8 : call fftprofs_print(Ftprof, header)
347 12 : call fftprofs_free(Ftprof)
348 : end do
349 : end do
350 : end if
351 :
352 : ! =======================
353 : ! ==== fourwf timing ====
354 : ! =======================
355 34 : if (test_fourwf) then
356 : ! possible combinations of (option, cplex) supported in fourwf.
357 : ! (cplex=2 only allowed for option=2, and istwf_k=1)
358 22 : nsets=4; if (Ftest(1)%istwf_k==1) nsets=5
359 22 : ABI_MALLOC(fourwf_params,(2,nsets))
360 66 : fourwf_params(:,1) = [0, 0]
361 66 : fourwf_params(:,2) = [1, 1]
362 66 : fourwf_params(:,3) = [2, 1]
363 66 : fourwf_params(:,4) = [3, 0]
364 30 : if (nsets==5) fourwf_params(:,5) = [2, 2]
365 :
366 114 : do iset=1,nsets
367 92 : option_fourwf = fourwf_params(1,iset)
368 92 : cplex = fourwf_params(2,iset)
369 818 : do it=1,ntests
370 818 : call Ftest(it)%time_fourwf(cplex, option_fourwf, header, Ftprof(it))
371 : end do
372 92 : call fftprofs_print(Ftprof, header)
373 114 : call fftprofs_free(Ftprof)
374 : end do
375 22 : ABI_FREE(fourwf_params)
376 : end if
377 :
378 : ! ==========================
379 : ! ==== Test GW routines ====
380 : ! ==========================
381 : ! These routines are used in the GW part, FFTW3 is expected to
382 : ! be more efficient as the conversion complex(:) <--> real(2,:) is not needed.
383 34 : if (test_gw) then
384 :
385 : ! fourdp timing with complex arrays
386 6 : do isign=-1,1,2
387 14 : do inplace=0,1
388 32 : do it=1,ntests
389 32 : call Ftest(it)%time_fftbox(isign, inplace, header, Ftprof(it))
390 : end do
391 8 : call fftprofs_print(Ftprof, header)
392 12 : call fftprofs_free(Ftprof)
393 : end do
394 : end do
395 :
396 : ! zero padded FFTs with complex arrays
397 6 : do isign=-1,1,2
398 16 : do it=1,ntests
399 16 : call Ftest(it)%time_fftu(isign, header, Ftprof(it))
400 : end do
401 4 : call fftprofs_print(Ftprof, header)
402 6 : call fftprofs_free(Ftprof)
403 : end do
404 :
405 : ! rho_tw_g timing
406 2 : ABI_CHECK(osc_ecut > zero, "osc_ecut <= zero!")
407 :
408 2 : call get_kg(gamma_point,1,osc_ecut,gmet,osc_npw,osc_gvec)
409 : ! TODO should reorder by shells to be consistent with the GW part!
410 : ! Moreover I guess this ordering is more efficient when we have
411 : ! to map the box to the G-sphere!
412 2 : map2sphere=1; !map2sphere=0
413 :
414 6 : do use_padfft=0,1
415 16 : do it=1,ntests
416 16 : call Ftest(it)%time_rhotwg(map2sphere, use_padfft, osc_npw, osc_gvec, header, Ftprof(it))
417 : end do
418 4 : call fftprofs_print(Ftprof, header)
419 6 : call fftprofs_free(Ftprof)
420 : end do
421 :
422 2 : ABI_FREE(osc_gvec)
423 : end if ! test_gw
424 :
425 34 : if (do_seq_utests) then
426 8 : call wrtout(std_out, "=== FFT Unit Tests ===")
427 8 : nfailed = 0
428 16 : do idx=1,ntests
429 : ! fft_setups(:,idx) = [fftalg,fftcache,ndat,ith,avail,gpu_option]
430 8 : fftalg = fft_setups(1, idx)
431 8 : fftcache = fft_setups(2, idx)
432 8 : ndat = fft_setups(3, idx)
433 8 : nthreads = fft_setups(4, idx)
434 : ! Skip the test if library is not available.
435 8 : if (fft_setups(5, idx) == 0) CYCLE
436 8 : gpu_option = fft_setups(6, idx)
437 :
438 8 : write(msg,"(3(a,i0))")"fftbox_utests with fftalg = ",fftalg,", ndat = ",ndat,", nthreads = ",nthreads
439 : !write(msg,"(4(a,i0))")"fftbox_utests with fftalg = ",fftalg,", ndat = ",ndat,", nthreads = ",nthreads, ", gpu_option = ", gpu_option
440 8 : call wrtout(std_out, msg)
441 8 : nfailed = nfailed + fftbox_utests(fftalg, ndat, nthreads, gpu_option)
442 :
443 : ! Initialize ngfft(7:8) here.
444 152 : ut_ngfft = -1
445 8 : ut_ngfft(7) = fftalg
446 8 : ut_ngfft(8) = fftcache
447 :
448 : call getng(boxcutmin2,0,ecut,gmet,k0,me_fft0,ut_mgfft,ut_nfft,ut_ngfft,nproc_fft1,nsym,&
449 8 : paral_kgb0,symrel,tnons, unit=dev_null, gpu_option=gpu_option)
450 :
451 8 : write(msg,"(3(a,i0))")"fftu_utests with fftalg = ",fftalg,", ndat = ",ndat,", nthreads = ",nthreads
452 : !write(msg,"(4(a,i0))")"fftu_utests with fftalg = ",fftalg,", ndat = ",ndat,", nthreads = ",nthreads, ", gpu_option = ", gpu_option
453 8 : call wrtout(std_out, msg)
454 16 : nfailed = nfailed + fftu_utests(ecut, ut_ngfft, rprimd, ndat, nthreads)
455 :
456 : !write(msg,"(4(a,i0))")"uplan_utests with fftalg = ",fftalg,", ndat = ",ndat,", nthreads = ",nthreads, ", gpu_option = ", gpu_option
457 : !call wrtout(std_out, msg)
458 : !nfailed = nfailed + uplan_utests(ecut, ut_ngfft, rprimd, ndat, nthreads, gpu_option)
459 : end do
460 :
461 8 : write(msg,'(a,i0)')"Total number of failed tests = ",nfailed
462 8 : call wrtout(std_out, msg)
463 : end if
464 :
465 : ! Benchmarks for the sequential version.
466 34 : if (do_seq_bench) then
467 0 : call wrtout(std_out, "Entering benchmark mode")
468 0 : write(std_out,*)"ecut_arth",ecut_arth,", necut ",necut
469 :
470 0 : if (INDEX(tasks, "bench_fourdp") > 0) then
471 0 : isign=1; cplex=1
472 0 : call prof_fourdp(fft_setups, isign, cplex, necut, ecut_arth, boxcutmin2, rprimd, nsym, symrel, MPI_enreg)
473 :
474 0 : isign=1; cplex=2
475 0 : call prof_fourdp(fft_setups, isign, cplex, necut, ecut_arth, boxcutmin2, rprimd, nsym, symrel, MPI_enreg)
476 : end if
477 :
478 0 : if (INDEX(tasks, "bench_fourwf") > 0) then
479 0 : cplex=2; option_fourwf=0
480 0 : call prof_fourwf(fft_setups,cplex,option_fourwf,kpoint,necut,ecut_arth,boxcutmin2,rprimd,nsym,symrel,MPI_enreg)
481 :
482 0 : cplex=1; option_fourwf=1
483 0 : call prof_fourwf(fft_setups,cplex,option_fourwf,kpoint,necut,ecut_arth,boxcutmin2,rprimd,nsym,symrel,MPI_enreg)
484 :
485 0 : cplex=1; option_fourwf=2
486 0 : call prof_fourwf(fft_setups,cplex,option_fourwf,kpoint,necut,ecut_arth,boxcutmin2,rprimd,nsym,symrel,MPI_enreg)
487 :
488 0 : cplex=2; option_fourwf=2
489 0 : call prof_fourwf(fft_setups,cplex,option_fourwf,kpoint,necut,ecut_arth,boxcutmin2,rprimd,nsym,symrel,MPI_enreg)
490 :
491 0 : cplex=0; option_fourwf=3
492 0 : call prof_fourwf(fft_setups,cplex,option_fourwf,kpoint,necut,ecut_arth,boxcutmin2,rprimd,nsym,symrel,MPI_enreg)
493 : end if
494 :
495 0 : if (INDEX(tasks, "bench_rhotwg") > 0) then
496 0 : map2sphere = 1; use_padfft = 1
497 : call prof_rhotwg(fft_setups,map2sphere,use_padfft,necut,ecut_arth,osc_ecut,boxcutmin2,&
498 0 : rprimd,nsym,symrel,gmet,MPI_enreg)
499 :
500 0 : map2sphere = 1; use_padfft = 0
501 : call prof_rhotwg(fft_setups,map2sphere,use_padfft,necut,ecut_arth,osc_ecut,boxcutmin2,&
502 0 : rprimd,nsym,symrel,gmet,MPI_enreg)
503 : end if
504 : end if
505 :
506 : !===============================
507 : !=== End of run, free memory ===
508 : !===============================
509 34 : call wrtout(std_out,ch10//" Analysis completed.")
510 :
511 34 : ABI_FREE(fft_setups)
512 34 : call fft_tests_free(Ftest)
513 264 : ABI_FREE(Ftest)
514 34 : call fftprofs_free(Ftprof)
515 264 : ABI_FREE(Ftprof)
516 34 : call destroy_mpi_enreg(MPI_enreg)
517 :
518 : !call abi_linalg_finalize(init_gpu_flavor)
519 :
520 : #if defined HAVE_GPU_CUDA
521 : if (init_gpu_flavor /= ABI_GPU_DISABLED) then
522 : call gpu_linalg_shutdown()
523 : call unsetdevice_cuda(init_gpu_flavor)
524 : end if
525 : #endif
526 :
527 34 : call flush_unit(std_out)
528 34 : call abinit_doctor("__fftprof")
529 38 : 100 call xmpi_end()
530 :
531 34 : end program fftprof
532 : !!***
|