LCOV - code coverage report
Current view: top level - src/pw/fft - fft_lib.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:375a5ce) Lines: 83.5 % 79 66
Test Date: 2026-09-04 07:06:59 Functions: 88.9 % 9 8

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : MODULE fft_lib
       8              : 
       9              :    USE fft_kinds,                       ONLY: dp
      10              :    USE fft_plan,                        ONLY: fft_plan_type
      11              :    USE fftsg_lib,                       ONLY: fftsg1dm,&
      12              :                                               fftsg3d,&
      13              :                                               fftsg_do_cleanup,&
      14              :                                               fftsg_do_init
      15              :    USE fftw3_lib,                       ONLY: &
      16              :         fft_alloc => fftw_alloc, fft_dealloc => fftw_dealloc, fftw31dm, fftw33d, &
      17              :         fftw3_create_plan_1d, fftw3_create_plan_3d, fftw3_destroy_plan, fftw3_do_cleanup, &
      18              :         fftw3_do_init, fftw3_get_lengths
      19              : #include "../../base/base_uses.f90"
      20              : 
      21              :    IMPLICIT NONE
      22              :    PRIVATE
      23              : 
      24              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'fft_lib'
      25              : 
      26              :    INTEGER, SAVE :: fft_type = 0
      27              : 
      28              :    PUBLIC :: fft_do_cleanup, fft_do_init, fft_get_lengths, fft_create_plan_3d
      29              :    PUBLIC :: fft_create_plan_1d, fft_1d, fft_library, fft_3d, fft_destroy_plan
      30              :    PUBLIC :: fft_alloc, fft_dealloc
      31              : 
      32              : CONTAINS
      33              : ! **************************************************************************************************
      34              : !> \brief Interface to FFT libraries
      35              : !> \param fftlib ...
      36              : !> \return ...
      37              : !> \par History
      38              : !>      IAB 09-Jan-2009 : Modified to use fft_plan_type
      39              : !>                        (c) The Numerical Algorithms Group (NAG) Ltd, 2009 on behalf of the HECToR project
      40              : !> \author JGH
      41              : ! **************************************************************************************************
      42        11469 :    FUNCTION fft_library(fftlib) RESULT(flib)
      43              : 
      44              :       CHARACTER(len=*), INTENT(IN)                       :: fftlib
      45              :       INTEGER                                            :: flib
      46              : 
      47              :       SELECT CASE (fftlib)
      48              :       CASE DEFAULT
      49           14 :          flib = -1
      50              :       CASE ("FFTSG")
      51           14 :          flib = 1
      52              :       CASE ("FFTW3")
      53        11469 :          flib = 3
      54              :       END SELECT
      55              : 
      56        11469 :    END FUNCTION fft_library
      57              : 
      58              : ! **************************************************************************************************
      59              : !> \brief ...
      60              : !> \param fftlib ...
      61              : !> \param plan_style ...
      62              : !> \param wisdom_file ...
      63              : ! **************************************************************************************************
      64        11469 :    SUBROUTINE fft_do_init(fftlib, plan_style, wisdom_file)
      65              :       CHARACTER(LEN=*), INTENT(IN)                       :: fftlib
      66              :       INTEGER, INTENT(IN)                                :: plan_style
      67              :       CHARACTER(LEN=*), INTENT(IN)                       :: wisdom_file
      68              : 
      69        11469 :       fft_type = fft_library(fftlib)
      70            0 :       SELECT CASE (fft_type)
      71              :       CASE DEFAULT
      72            0 :          CPABORT("fft_do_init")
      73              :       CASE (1)
      74           14 :          CALL fftsg_do_init()
      75              :       CASE (3)
      76        11469 :          CALL fftw3_do_init(wisdom_file, plan_style)
      77              :       END SELECT
      78              : 
      79        11469 :    END SUBROUTINE fft_do_init
      80              : 
      81              : ! **************************************************************************************************
      82              : !> \brief ...
      83              : !> \param wisdom_file ...
      84              : !> \param ionode ...
      85              : ! **************************************************************************************************
      86        11259 :    SUBROUTINE fft_do_cleanup(wisdom_file, ionode)
      87              :       CHARACTER(LEN=*), INTENT(IN)                       :: wisdom_file
      88              :       LOGICAL, INTENT(IN)                                :: ionode
      89              : 
      90            0 :       SELECT CASE (fft_type)
      91              :       CASE DEFAULT
      92            0 :          CPABORT("fft_do_cleanup")
      93              :       CASE (1)
      94           14 :          CALL fftsg_do_cleanup()
      95              :       CASE (3)
      96        11259 :          CALL fftw3_do_cleanup(wisdom_file, ionode)
      97              :       END SELECT
      98              : 
      99        11259 :    END SUBROUTINE fft_do_cleanup
     100              : 
     101              : ! **************************************************************************************************
     102              : !> \brief ...
     103              : !> \param DATA ...
     104              : !> \param max_length ...
     105              : ! **************************************************************************************************
     106            0 :    SUBROUTINE fft_get_lengths(DATA, max_length)
     107              :       INTEGER, DIMENSION(*)                              :: DATA
     108              :       INTEGER, INTENT(INOUT)                             :: max_length
     109              : 
     110            0 :       CALL fftw3_get_lengths(DATA, max_length)
     111              : 
     112            0 :    END SUBROUTINE fft_get_lengths
     113              : 
     114              : ! **************************************************************************************************
     115              : 
     116              : ! **************************************************************************************************
     117              : !> \brief ...
     118              : !> \param plan ...
     119              : !> \param fft_in_place ...
     120              : !> \param fsign ...
     121              : !> \param n ...
     122              : !> \param zin ...
     123              : !> \param zout ...
     124              : ! **************************************************************************************************
     125        62892 :    SUBROUTINE fft_create_plan_3d(plan, fft_in_place, fsign, n, zin, zout)
     126              : 
     127              :       TYPE(fft_plan_type), INTENT(INOUT)                 :: plan
     128              :       LOGICAL, INTENT(IN)                                :: fft_in_place
     129              :       INTEGER, INTENT(IN)                                :: fsign
     130              :       INTEGER, DIMENSION(3), INTENT(IN)                  :: n
     131              :       COMPLEX(KIND=dp), DIMENSION(*), INTENT(INOUT)      :: zin, zout
     132              : 
     133        62892 :       plan%fsign = fsign
     134        62892 :       plan%fft_in_place = fft_in_place
     135       251568 :       plan%n_3d = n
     136        62892 : !$    plan%need_alt_plan = .FALSE.
     137              : 
     138              :       ! Planning only needed for FFTW3
     139        62892 :       IF (fft_type == 3) THEN
     140        62740 :          CALL fftw3_create_plan_3d(plan, zin, zout)
     141        62740 :          plan%valid = .TRUE.
     142              :       END IF
     143              : 
     144        62892 :    END SUBROUTINE fft_create_plan_3d
     145              : 
     146              : !
     147              : ! really ugly, plan is intent out, because plan%fsign is also a status flag
     148              : ! if something goes wrong, plan%fsign is set to zero, and the plan becomes invalid
     149              : !
     150              : ! **************************************************************************************************
     151              : !> \brief ...
     152              : !> \param plan ...
     153              : !> \param scale ...
     154              : !> \param zin ...
     155              : !> \param zout ...
     156              : !> \param stat ...
     157              : ! **************************************************************************************************
     158       663347 :    SUBROUTINE fft_3d(plan, scale, zin, zout, stat)
     159              :       TYPE(fft_plan_type), INTENT(IN)                    :: plan
     160              :       REAL(KIND=dp), INTENT(IN)                          :: scale
     161              :       COMPLEX(KIND=dp), DIMENSION(*), INTENT(INOUT)      :: zin, zout
     162              :       INTEGER, INTENT(OUT)                               :: stat
     163              : 
     164       663347 :       stat = plan%fsign
     165       663347 :       IF (plan%n_3d(1)*plan%n_3d(2)*plan%n_3d(3) > 0) THEN
     166            0 :          SELECT CASE (fft_type)
     167              :          CASE DEFAULT
     168            0 :             CPABORT("fft_3d")
     169              :          CASE (1)
     170         2964 :             CALL fftsg3d(plan%fft_in_place, stat, scale, plan%n_3d, zin, zout)
     171              :          CASE (3)
     172       663347 :             CALL fftw33d(plan, scale, zin, zout, stat)
     173              :          END SELECT
     174              :       END IF
     175              :       ! stat is set to zero on error, -1,+1 are OK
     176       663347 :       IF (stat == 0) THEN
     177            0 :          stat = 1
     178              :       ELSE
     179       663347 :          stat = 0
     180              :       END IF
     181              : 
     182       663347 :    END SUBROUTINE fft_3d
     183              : 
     184              : ! **************************************************************************************************
     185              : 
     186              : ! **************************************************************************************************
     187              : !> \brief ...
     188              : !> \param plan ...
     189              : !> \param fsign ...
     190              : !> \param trans_in ...
     191              : !> \param trans_out ...
     192              : !> \param ldx_in ...
     193              : !> \param ldx_out ...
     194              : !> \param n ...
     195              : !> \param m ...
     196              : !> \param zin ...
     197              : !> \param zout ...
     198              : ! **************************************************************************************************
     199       463634 :    SUBROUTINE fft_create_plan_1d(plan, fsign, trans_in, trans_out, ldx_in, ldx_out, n, m, zin, zout)
     200              :       TYPE(fft_plan_type), INTENT(INOUT)                 :: plan
     201              :       INTEGER, INTENT(IN)                                :: fsign
     202              :       LOGICAL, INTENT(IN)                                :: trans_in, trans_out
     203              :       INTEGER, INTENT(IN)                                :: ldx_in, ldx_out, n, m
     204              :       COMPLEX(KIND=dp), DIMENSION(*), INTENT(IN)         :: zin, zout
     205              : 
     206       463634 :       plan%fsign = fsign
     207       463634 :       plan%trans_in = trans_in
     208       463634 :       plan%trans_out = trans_out
     209       463634 :       IF (plan%trans_in) THEN
     210       360605 :          plan%ldx_in = ldx_in
     211       360605 :          plan%ldy_in = n
     212              :       ELSE
     213       103029 :          plan%ldx_in = ldx_in
     214       103029 :          plan%ldy_in = m
     215              :       END IF
     216       463634 :       IF (plan%trans_out) THEN
     217       360605 :          plan%ldx_out = ldx_out
     218       360605 :          plan%ldy_out = n
     219              :       ELSE
     220       103029 :          plan%ldx_out = ldx_out
     221       103029 :          plan%ldy_out = m
     222              :       END IF
     223              : 
     224       463634 :       plan%n = n
     225       463634 :       plan%m = m
     226       463634 : !$    plan%need_alt_plan = .FALSE.
     227              : 
     228              :       ! Planning only needed for FFTW3
     229       463634 :       IF ((fft_type == 3) .AND. (n*m /= 0)) THEN
     230       462278 :          CALL fftw3_create_plan_1d(plan, zin, zout)
     231       462278 :          plan%valid = .TRUE.
     232              :       ELSE
     233         1356 :          plan%valid = .FALSE.
     234              :       END IF
     235              : 
     236       463634 :    END SUBROUTINE fft_create_plan_1d
     237              : 
     238              : ! **************************************************************************************************
     239              : !> \brief ...
     240              : !> \param plan ...
     241              : ! **************************************************************************************************
     242       706910 :    SUBROUTINE fft_destroy_plan(plan)
     243              :       TYPE(fft_plan_type), INTENT(INOUT)                 :: plan
     244              : 
     245              : ! Planning only needed for FFTW3
     246              : 
     247       706910 :       IF (plan%valid .AND. fft_type == 3) THEN
     248       525018 :          CALL fftw3_destroy_plan(plan)
     249       525018 :          plan%valid = .FALSE.
     250              :       END IF
     251              : 
     252       706910 :    END SUBROUTINE fft_destroy_plan
     253              : 
     254              : ! **************************************************************************************************
     255              : !> \brief ...
     256              : !> \param plan ...
     257              : !> \param zin ...
     258              : !> \param zout ...
     259              : !> \param scale ...
     260              : !> \param stat ...
     261              : ! **************************************************************************************************
     262     19999300 :    SUBROUTINE fft_1d(plan, zin, zout, scale, stat)
     263              :       TYPE(fft_plan_type), INTENT(IN)                    :: plan
     264              :       COMPLEX(KIND=dp), DIMENSION(*), INTENT(INOUT)      :: zin, zout
     265              :       REAL(KIND=dp), INTENT(IN)                          :: scale
     266              :       INTEGER, INTENT(OUT)                               :: stat
     267              : 
     268     19999300 :       stat = plan%fsign
     269     19999300 :       IF (plan%n*plan%m > 0) THEN
     270            0 :          SELECT CASE (fft_type)
     271              :          CASE DEFAULT
     272            0 :             CPABORT("fft_1d")
     273              :          CASE (1)
     274              :             CALL fftsg1dm(stat, plan%trans_in, plan%trans_out, plan%n, plan%m, &
     275        30238 :                           plan%ldx_in, plan%ldy_in, plan%ldx_out, plan%ldy_out, zin, zout, scale)
     276              :          CASE (3)
     277     19999300 :             CALL fftw31dm(plan, zin, zout, scale, stat)
     278              :          END SELECT
     279              :       END IF
     280              :       ! stat is set to zero on error, -1,+1 are OK
     281     19999300 :       IF (stat == 0) THEN
     282            0 :          stat = 1
     283              :       ELSE
     284     19999300 :          stat = 0
     285              :       END IF
     286              : 
     287     19999300 :    END SUBROUTINE fft_1d
     288              : 
     289              : END MODULE fft_lib
        

Generated by: LCOV version 2.0-1