tpm_hicfft.F90 Source File


This file depends on

sourcefile~~tpm_hicfft.f90~~EfferentGraph sourcefile~tpm_hicfft.f90 tpm_hicfft.F90 sourcefile~growing_allocator_mod.f90 growing_allocator_mod.F90 sourcefile~tpm_hicfft.f90->sourcefile~growing_allocator_mod.f90 sourcefile~abort_trans_mod.f90 abort_trans_mod.F90 sourcefile~growing_allocator_mod.f90->sourcefile~abort_trans_mod.f90 sourcefile~tpm_gen.f90 tpm_gen.F90 sourcefile~growing_allocator_mod.f90->sourcefile~tpm_gen.f90 sourcefile~abort_trans_mod.f90->sourcefile~tpm_gen.f90

Files dependent on this one

sourcefile~~tpm_hicfft.f90~~AfferentGraph sourcefile~tpm_hicfft.f90 tpm_hicfft.F90 sourcefile~dealloc_resol_mod.f90 dealloc_resol_mod.F90 sourcefile~dealloc_resol_mod.f90->sourcefile~tpm_hicfft.f90 sourcefile~ftdir_mod.f90 ftdir_mod.F90 sourcefile~ftdir_mod.f90->sourcefile~tpm_hicfft.f90 sourcefile~ftinv_mod.f90 ftinv_mod.F90 sourcefile~ftinv_mod.f90->sourcefile~tpm_hicfft.f90 sourcefile~dir_trans_ctl_mod.f90 dir_trans_ctl_mod.F90 sourcefile~dir_trans_ctl_mod.f90->sourcefile~ftdir_mod.f90 sourcefile~ftdir_ctl_mod.f90 ftdir_ctl_mod.F90 sourcefile~ftdir_ctl_mod.f90->sourcefile~ftdir_mod.f90 sourcefile~ftinv_ctl_mod.f90 ftinv_ctl_mod.F90 sourcefile~ftinv_ctl_mod.f90->sourcefile~ftinv_mod.f90 sourcefile~inv_trans_ctl_mod.f90 inv_trans_ctl_mod.F90 sourcefile~inv_trans_ctl_mod.f90->sourcefile~ftinv_mod.f90 sourcefile~trans_end.f90 trans_end.F90 sourcefile~trans_end.f90->sourcefile~dealloc_resol_mod.f90 sourcefile~trans_end.f90~2 trans_end.F90 sourcefile~trans_end.f90~2->sourcefile~dealloc_resol_mod.f90 sourcefile~trans_release.f90 trans_release.F90 sourcefile~trans_release.f90->sourcefile~dealloc_resol_mod.f90 sourcefile~trans_release.f90~2 trans_release.F90 sourcefile~trans_release.f90~2->sourcefile~dealloc_resol_mod.f90 sourcefile~dir_trans.f90 dir_trans.F90 sourcefile~dir_trans.f90->sourcefile~dir_trans_ctl_mod.f90 sourcefile~dir_trans.f90~2 dir_trans.F90 sourcefile~dir_trans.f90~2->sourcefile~dir_trans_ctl_mod.f90 sourcefile~dir_trans_ctl_mod.f90~2 dir_trans_ctl_mod.F90 sourcefile~dir_trans_ctl_mod.f90~2->sourcefile~ftdir_ctl_mod.f90 sourcefile~inv_trans.f90 inv_trans.F90 sourcefile~inv_trans.f90->sourcefile~inv_trans_ctl_mod.f90 sourcefile~inv_trans.f90~2 inv_trans.F90 sourcefile~inv_trans.f90~2->sourcefile~inv_trans_ctl_mod.f90 sourcefile~inv_trans_ctl_mod.f90~2 inv_trans_ctl_mod.F90 sourcefile~inv_trans_ctl_mod.f90~2->sourcefile~ftinv_ctl_mod.f90

Source Code

! (C) Copyright 2014- ECMWF.
! (C) Copyright 2022- NVIDIA.
!
! This software is licensed under the terms of the Apache Licence Version 2.0
! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
! In applying this licence, ECMWF does not waive the privileges and immunities
! granted to it by virtue of its status as an intergovernmental organisation
! nor does it submit to any jurisdiction.
!

MODULE TPM_HICFFT

  !   Author.
  !   -------
  !     George Mozdzynski
  !
  !   Modifications.
  !   --------------
  !     Original      October 2014
  !     HICFFT abstraction for CUDA and HIP     August 2023     B. Reuter

  USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_FLOAT, C_DOUBLE, C_LOC
  USE GROWING_ALLOCATOR_MOD,       ONLY: GROWING_ALLOCATION_TYPE

  IMPLICIT NONE

  SAVE

  PRIVATE
  PUBLIC EXECUTE_DIR_FFT, EXECUTE_INV_FFT
  PUBLIC CLEAN_FFT

INTERFACE EXECUTE_DIR_FFT
  MODULE PROCEDURE EXECUTE_DIR_FFT_FLOAT,EXECUTE_DIR_FFT_DOUBLE
END INTERFACE

INTERFACE EXECUTE_INV_FFT
  MODULE PROCEDURE EXECUTE_INV_FFT_FLOAT,EXECUTE_INV_FFT_DOUBLE
END INTERFACE

INTERFACE
  SUBROUTINE CLEAN_FFT(RESOL_ID) BIND(C, NAME="clean_fft")
    USE ISO_C_BINDING
    INTEGER(KIND=C_INT), INTENT(IN), VALUE :: RESOL_ID
  END SUBROUTINE
END INTERFACE



  ! ------------------------------------------------------------------
  CONTAINS
  ! ------------------------------------------------------------------


SUBROUTINE EXECUTE_DIR_FFT_FLOAT(PREEL_REAL,PREEL_COMPLEX,RESOL_ID,KFIELD,LOENS,OFFSETS,ALLOC)
  USE EC_PARKIND ,ONLY : JPIM, JPIB

  IMPLICIT NONE

  REAL(KIND=C_FLOAT), INTENT(IN) :: PREEL_REAL(:)
  REAL(KIND=C_FLOAT), INTENT(OUT) :: PREEL_COMPLEX(:)
  INTEGER(KIND=JPIM),INTENT(IN)  :: RESOL_ID
  INTEGER(KIND=JPIM),INTENT(IN)  :: KFIELD
  INTEGER(KIND=JPIM),INTENT(IN)  :: LOENS(:)
  INTEGER(KIND=JPIB),INTENT(IN)  :: OFFSETS(:)
  TYPE(GROWING_ALLOCATION_TYPE), INTENT(IN), POINTER :: ALLOC
  INTERFACE
    SUBROUTINE EXECUTE_DIR_FFT_FLOAT_C(PREEL_REAL,PREEL_COMPLEX,RESOL_ID,KFIELD,LOENS,OFFSETS,NFFT,ALLOC) &
 &                   BIND(C, NAME="execute_dir_fft_float")
      USE ISO_C_BINDING, ONLY: C_FLOAT, C_INT, C_PTR, C_INT64_T
      REAL(KIND=C_FLOAT), INTENT(IN) :: PREEL_REAL(*)
      REAL(KIND=C_FLOAT), INTENT(OUT) :: PREEL_COMPLEX(*)
      INTEGER(KIND=C_INT),INTENT(IN),VALUE  :: RESOL_ID
      INTEGER(KIND=C_INT),INTENT(IN),VALUE  :: KFIELD
      INTEGER(KIND=C_INT),INTENT(IN)  :: LOENS(*)
      INTEGER(KIND=C_INT64_T),INTENT(IN)  :: OFFSETS(*)
      INTEGER(KIND=C_INT),INTENT(IN),VALUE :: NFFT
      TYPE(C_PTR), INTENT(IN), VALUE :: ALLOC
    END SUBROUTINE
  END INTERFACE

#ifdef ACCGPU
  !$ACC HOST_DATA USE_DEVICE(PREEL_REAL,PREEL_COMPLEX)
#endif
  CALL EXECUTE_DIR_FFT_FLOAT_C(PREEL_REAL,PREEL_COMPLEX,RESOL_ID,KFIELD,LOENS,OFFSETS,SIZE(LOENS),C_LOC(ALLOC))
#ifdef ACCGPU
  !$ACC END HOST_DATA
#endif

END SUBROUTINE EXECUTE_DIR_FFT_FLOAT
SUBROUTINE EXECUTE_DIR_FFT_DOUBLE(PREEL_REAL,PREEL_COMPLEX,RESOL_ID,KFIELD,LOENS,OFFSETS,ALLOC)
  USE EC_PARKIND ,ONLY : JPIM, JPIB

  IMPLICIT NONE

  REAL(KIND=C_DOUBLE), INTENT(IN) :: PREEL_REAL(:)
  REAL(KIND=C_DOUBLE), INTENT(OUT) :: PREEL_COMPLEX(:)
  INTEGER(KIND=JPIM),INTENT(IN)  :: RESOL_ID
  INTEGER(KIND=JPIM),INTENT(IN)  :: KFIELD
  INTEGER(KIND=JPIM),INTENT(IN)  :: LOENS(:)
  INTEGER(KIND=JPIB),INTENT(IN)  :: OFFSETS(:)
  TYPE(GROWING_ALLOCATION_TYPE), INTENT(IN), POINTER :: ALLOC
  INTERFACE
    SUBROUTINE EXECUTE_DIR_FFT_DOUBLE_C(PREEL_REAL,PREEL_COMPLEX,RESOL_ID,KFIELD,LOENS,OFFSETS,NFFT,ALLOC) &
 &                   BIND(C, NAME="execute_dir_fft_double")
      USE ISO_C_BINDING, ONLY: C_DOUBLE, C_INT, C_PTR, C_INT64_T
      REAL(KIND=C_DOUBLE), INTENT(IN) :: PREEL_REAL(*)
      REAL(KIND=C_DOUBLE), INTENT(OUT) :: PREEL_COMPLEX(*)
      INTEGER(KIND=C_INT),INTENT(IN),VALUE  :: RESOL_ID
      INTEGER(KIND=C_INT),INTENT(IN),VALUE  :: KFIELD
      INTEGER(KIND=C_INT),INTENT(IN)  :: LOENS(*)
      INTEGER(KIND=C_INT64_T),INTENT(IN)  :: OFFSETS(*)
      INTEGER(KIND=C_INT),INTENT(IN),VALUE :: NFFT
      TYPE(C_PTR), INTENT(IN), VALUE :: ALLOC
    END SUBROUTINE
  END INTERFACE

#ifdef ACCGPU
  !$ACC HOST_DATA USE_DEVICE(PREEL_REAL,PREEL_COMPLEX)
#endif
  CALL EXECUTE_DIR_FFT_DOUBLE_C(PREEL_REAL,PREEL_COMPLEX,RESOL_ID,KFIELD,LOENS,OFFSETS,SIZE(LOENS),C_LOC(ALLOC))
#ifdef ACCGPU
  !$ACC END HOST_DATA
#endif

END SUBROUTINE EXECUTE_DIR_FFT_DOUBLE

SUBROUTINE EXECUTE_INV_FFT_FLOAT(PREEL_COMPLEX,PREEL_REAL,RESOL_ID,KFIELD,LOENS,OFFSETS,ALLOC)
  USE EC_PARKIND ,ONLY : JPIM, JPIB

  IMPLICIT NONE

  REAL(KIND=C_FLOAT), INTENT(IN) :: PREEL_COMPLEX(:)
  REAL(KIND=C_FLOAT), INTENT(OUT) :: PREEL_REAL(:)
  INTEGER(KIND=JPIM),INTENT(IN)  :: RESOL_ID
  INTEGER(KIND=JPIM),INTENT(IN)  :: KFIELD
  INTEGER(KIND=JPIM),INTENT(IN)  :: LOENS(:)
  INTEGER(KIND=JPIB),INTENT(IN)  :: OFFSETS(:)
  TYPE(GROWING_ALLOCATION_TYPE), INTENT(IN), POINTER :: ALLOC
  INTERFACE
    SUBROUTINE EXECUTE_INV_FFT_FLOAT_C(PREEL_COMPLEX,PREEL_REAL,RESOL_ID,KFIELD,LOENS,OFFSETS,NFFT,ALLOC) &
 &                   BIND(C, NAME="execute_inv_fft_float")
      USE ISO_C_BINDING, ONLY: C_FLOAT, C_INT, C_PTR, C_INT64_T
      REAL(KIND=C_FLOAT), INTENT(IN) :: PREEL_COMPLEX(*)
      REAL(KIND=C_FLOAT), INTENT(OUT) :: PREEL_REAL(*)
      INTEGER(KIND=C_INT),INTENT(IN),VALUE  :: RESOL_ID
      INTEGER(KIND=C_INT),INTENT(IN),VALUE  :: KFIELD
      INTEGER(KIND=C_INT),INTENT(IN)  :: LOENS(*)
      INTEGER(KIND=C_INT64_T),INTENT(IN)  :: OFFSETS(*)
      INTEGER(KIND=C_INT),INTENT(IN),VALUE :: NFFT
      TYPE(C_PTR), INTENT(IN), VALUE :: ALLOC
    END SUBROUTINE
  END INTERFACE

#ifdef ACCGPU
  !$ACC HOST_DATA USE_DEVICE(PREEL_COMPLEX,PREEL_REAL)
#endif
  CALL EXECUTE_INV_FFT_FLOAT_C(PREEL_COMPLEX,PREEL_REAL,RESOL_ID,KFIELD,LOENS,OFFSETS,SIZE(LOENS),C_LOC(ALLOC))
#ifdef ACCGPU
  !$ACC END HOST_DATA
#endif
END SUBROUTINE

SUBROUTINE EXECUTE_INV_FFT_DOUBLE(PREEL_COMPLEX,PREEL_REAL,RESOL_ID,KFIELD,LOENS,OFFSETS,ALLOC)
  USE EC_PARKIND ,ONLY : JPIM, JPIB

  IMPLICIT NONE

  REAL(KIND=C_DOUBLE), INTENT(IN) :: PREEL_COMPLEX(:)
  REAL(KIND=C_DOUBLE), INTENT(OUT) :: PREEL_REAL(:)
  INTEGER(KIND=JPIM),INTENT(IN)  :: RESOL_ID
  INTEGER(KIND=JPIM),INTENT(IN)  :: KFIELD
  INTEGER(KIND=JPIM),INTENT(IN)  :: LOENS(:)
  INTEGER(KIND=JPIB),INTENT(IN)  :: OFFSETS(:)
  TYPE(GROWING_ALLOCATION_TYPE), INTENT(IN), POINTER :: ALLOC
  INTERFACE
    SUBROUTINE EXECUTE_INV_FFT_DOUBLE_C(PREEL_COMPLEX,PREEL_REAL,RESOL_ID,KFIELD,LOENS,OFFSETS,NFFT,ALLOC) &
 &                   BIND(C, NAME="execute_inv_fft_double")
      USE ISO_C_BINDING, ONLY: C_DOUBLE, C_INT, C_PTR, C_INT64_T
      REAL(KIND=C_DOUBLE), INTENT(IN) :: PREEL_COMPLEX(*)
      REAL(KIND=C_DOUBLE), INTENT(OUT) :: PREEL_REAL(*)
      INTEGER(KIND=C_INT),INTENT(IN),VALUE  :: RESOL_ID
      INTEGER(KIND=C_INT),INTENT(IN),VALUE  :: KFIELD
      INTEGER(KIND=C_INT),INTENT(IN)  :: LOENS(*)
      INTEGER(KIND=C_INT64_T),INTENT(IN)  :: OFFSETS(*)
      INTEGER(KIND=C_INT),INTENT(IN),VALUE :: NFFT
      TYPE(C_PTR), INTENT(IN), VALUE :: ALLOC
    END SUBROUTINE
  END INTERFACE

#ifdef ACCGPU
  !$ACC HOST_DATA USE_DEVICE(PREEL_COMPLEX,PREEL_REAL)
#endif
  CALL EXECUTE_INV_FFT_DOUBLE_C(PREEL_COMPLEX,PREEL_REAL,RESOL_ID,KFIELD,LOENS,OFFSETS,SIZE(LOENS),C_LOC(ALLOC))
#ifdef ACCGPU
  !$ACC END HOST_DATA
#endif
END SUBROUTINE


END MODULE TPM_HICFFT