LCOV - code coverage report
Current view: top level - src/70_gw - m_fft_prof.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.8 % 576 431
Test Date: 2026-11-08 00:10:28 Functions: 73.9 % 23 17
Branches: 50.7 % 1275 646

             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                 :             : !!***
        

Generated by: LCOV version 2.3-1