dtfft_parameters.F90 Source File


Files dependent on this one

sourcefile~~dtfft_parameters.f90~~AfferentGraph sourcefile~dtfft_parameters.f90 dtfft_parameters.F90 sourcefile~dtfft.f90 dtfft.F90 sourcefile~dtfft.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_config.f90 dtfft_config.F90 sourcefile~dtfft.f90->sourcefile~dtfft_config.f90 sourcefile~dtfft_pencil.f90 dtfft_pencil.F90 sourcefile~dtfft.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_plan.f90 dtfft_plan.F90 sourcefile~dtfft.f90->sourcefile~dtfft_plan.f90 sourcefile~dtfft_abstract_backend.f90 dtfft_abstract_backend.F90 sourcefile~dtfft_abstract_backend.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_interface_cuda_runtime.f90 dtfft_interface_cuda_runtime.F90 sourcefile~dtfft_abstract_backend.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_interface_nccl.f90 dtfft_interface_nccl.F90 sourcefile~dtfft_abstract_backend.f90->sourcefile~dtfft_interface_nccl.f90 sourcefile~dtfft_nvrtc_kernel.f90 dtfft_nvrtc_kernel.F90 sourcefile~dtfft_abstract_backend.f90->sourcefile~dtfft_nvrtc_kernel.f90 sourcefile~dtfft_abstract_backend.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_utils.f90 dtfft_utils.F90 sourcefile~dtfft_abstract_backend.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_abstract_executor.f90 dtfft_abstract_executor.F90 sourcefile~dtfft_abstract_executor.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_abstract_executor.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_abstract_executor.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_interface_nvtx.f90 dtfft_interface_nvtx.F90 sourcefile~dtfft_abstract_executor.f90->sourcefile~dtfft_interface_nvtx.f90 sourcefile~dtfft_abstract_transpose_plan.f90 dtfft_abstract_transpose_plan.F90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_abstract_backend.f90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_config.f90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_interface_nccl.f90 sourcefile~dtfft_interface_nvshmem.f90 dtfft_interface_nvshmem.F90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_interface_nvshmem.f90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_nvrtc_kernel.f90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_abstract_transpose_plan.f90->sourcefile~dtfft_interface_nvtx.f90 sourcefile~dtfft_api.f90 dtfft_api.F90 sourcefile~dtfft_api.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_api.f90->sourcefile~dtfft_config.f90 sourcefile~dtfft_api.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_api.f90->sourcefile~dtfft_plan.f90 sourcefile~dtfft_api.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_backend_cufftmp.f90 dtfft_backend_cufftmp.F90 sourcefile~dtfft_backend_cufftmp.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_backend_cufftmp.f90->sourcefile~dtfft_abstract_backend.f90 sourcefile~dtfft_backend_cufftmp.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_interface_cufft.f90 dtfft_interface_cufft.F90 sourcefile~dtfft_backend_cufftmp.f90->sourcefile~dtfft_interface_cufft.f90 sourcefile~dtfft_backend_cufftmp.f90->sourcefile~dtfft_interface_nvshmem.f90 sourcefile~dtfft_backend_cufftmp.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_backend_cufftmp.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_backend_mpi.f90 dtfft_backend_mpi.F90 sourcefile~dtfft_backend_mpi.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_backend_mpi.f90->sourcefile~dtfft_abstract_backend.f90 sourcefile~dtfft_backend_mpi.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_backend_mpi.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_backend_nccl.f90 dtfft_backend_nccl.F90 sourcefile~dtfft_backend_nccl.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_backend_nccl.f90->sourcefile~dtfft_abstract_backend.f90 sourcefile~dtfft_backend_nccl.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_backend_nccl.f90->sourcefile~dtfft_interface_nccl.f90 sourcefile~dtfft_backend_nccl.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_config.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_config.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_config.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_executor_cufft_m.f90 dtfft_executor_cufft_m.F90 sourcefile~dtfft_executor_cufft_m.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_executor_cufft_m.f90->sourcefile~dtfft_abstract_executor.f90 sourcefile~dtfft_executor_cufft_m.f90->sourcefile~dtfft_config.f90 sourcefile~dtfft_executor_cufft_m.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_executor_cufft_m.f90->sourcefile~dtfft_interface_cufft.f90 sourcefile~dtfft_executor_cufft_m.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_executor_fftw_m.f90 dtfft_executor_fftw_m.F90 sourcefile~dtfft_executor_fftw_m.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_executor_fftw_m.f90->sourcefile~dtfft_abstract_executor.f90 sourcefile~dtfft_executor_fftw_m.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_executor_fftw_m.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_executor_mkl_m.f90 dtfft_executor_mkl_m.F90 sourcefile~dtfft_executor_mkl_m.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_executor_mkl_m.f90->sourcefile~dtfft_abstract_executor.f90 sourcefile~dtfft_executor_mkl_m.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_interface_mkl_m.f90 dtfft_interface_mkl_m.F90 sourcefile~dtfft_executor_mkl_m.f90->sourcefile~dtfft_interface_mkl_m.f90 sourcefile~dtfft_executor_vkfft_m.f90 dtfft_executor_vkfft_m.F90 sourcefile~dtfft_executor_vkfft_m.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_executor_vkfft_m.f90->sourcefile~dtfft_abstract_executor.f90 sourcefile~dtfft_executor_vkfft_m.f90->sourcefile~dtfft_config.f90 sourcefile~dtfft_interface_vkfft_m.f90 dtfft_interface_vkfft_m.F90 sourcefile~dtfft_executor_vkfft_m.f90->sourcefile~dtfft_interface_vkfft_m.f90 sourcefile~dtfft_interface_cuda.f90 dtfft_interface_cuda.F90 sourcefile~dtfft_interface_cuda.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_interface_cuda.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_interface_cuda.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_interface_cuda_runtime.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_interface_cuda_runtime.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_interface_cufft.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_interface_cufft.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_interface_nccl.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_interface_nccl.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_interface_nvrtc.f90 dtfft_interface_nvrtc.F90 sourcefile~dtfft_interface_nvrtc.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_interface_nvrtc.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_interface_nvrtc.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_interface_nvshmem.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_interface_nvshmem.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_interface_vkfft_m.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_interface_vkfft_m.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_nvrtc_kernel.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_nvrtc_kernel.f90->sourcefile~dtfft_interface_cuda.f90 sourcefile~dtfft_nvrtc_kernel.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_nvrtc_kernel.f90->sourcefile~dtfft_interface_nvrtc.f90 sourcefile~dtfft_nvrtc_kernel.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_nvrtc_kernel.f90->sourcefile~dtfft_interface_nvtx.f90 sourcefile~dtfft_pencil.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_pencil.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_pencil.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_abstract_executor.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_abstract_transpose_plan.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_config.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_executor_cufft_m.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_executor_fftw_m.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_executor_mkl_m.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_executor_vkfft_m.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_interface_nvshmem.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_nvrtc_kernel.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_transpose_plan_cuda.f90 dtfft_transpose_plan_cuda.F90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_transpose_plan_cuda.f90 sourcefile~dtfft_transpose_plan_host.f90 dtfft_transpose_plan_host.F90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_transpose_plan_host.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_plan.f90->sourcefile~dtfft_interface_nvtx.f90 sourcefile~dtfft_transpose_handle_cuda.f90 dtfft_transpose_handle_cuda.F90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_abstract_backend.f90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_backend_cufftmp.f90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_backend_mpi.f90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_backend_nccl.f90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_nvrtc_kernel.f90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_transpose_handle_cuda.f90->sourcefile~dtfft_interface_nvtx.f90 sourcefile~dtfft_transpose_handle_host.f90 dtfft_transpose_handle_host.F90 sourcefile~dtfft_transpose_handle_host.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_transpose_handle_host.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_transpose_handle_host.f90->sourcefile~dtfft_interface_nvtx.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_abstract_backend.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_abstract_transpose_plan.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_config.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_interface_cuda.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_interface_cuda_runtime.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_interface_nvrtc.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_nvrtc_kernel.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_transpose_handle_cuda.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_transpose_plan_cuda.f90->sourcefile~dtfft_interface_nvtx.f90 sourcefile~dtfft_transpose_plan_host.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_transpose_plan_host.f90->sourcefile~dtfft_abstract_transpose_plan.f90 sourcefile~dtfft_transpose_plan_host.f90->sourcefile~dtfft_pencil.f90 sourcefile~dtfft_transpose_plan_host.f90->sourcefile~dtfft_transpose_handle_host.f90 sourcefile~dtfft_transpose_plan_host.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_transpose_plan_host.f90->sourcefile~dtfft_interface_nvtx.f90 sourcefile~dtfft_utils.f90->sourcefile~dtfft_parameters.f90 sourcefile~dtfft_interface_mkl_m.f90->sourcefile~dtfft_utils.f90 sourcefile~dtfft_interface_nvtx.f90->sourcefile~dtfft_utils.f90

Source Code

!------------------------------------------------------------------------------------------------
! Copyright (c) 2021, Oleg Shatrov
! All rights reserved.
! This file is part of dtFFT library.

! dtFFT is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.

! dtFFT is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.

! You should have received a copy of the GNU General Public License
! along with this program.  If not, see <https://www.gnu.org/licenses/>.
!------------------------------------------------------------------------------------------------
#include "dtfft_config.h"
module dtfft_parameters
!! This module defines common ``dtFFT`` parameters
use iso_c_binding,    only: c_int32_t, c_null_ptr, c_ptr
use iso_fortran_env,  only: int8, int32, int64, real32, real64
#include "dtfft_mpi.h"
#include "dtfft_private.h"
implicit none
private
public :: dtfft_execute_t, dtfft_transpose_t
public :: dtfft_executor_t, dtfft_effort_t
public :: dtfft_precision_t, dtfft_r2r_kind_t
public :: is_valid_execute_type, is_valid_transpose_type
public :: is_valid_executor, is_valid_effort
public :: is_valid_precision, is_valid_r2r_kind
public :: is_valid_dimension, is_valid_comm_type
public :: dtfft_get_error_string
public :: dtfft_get_version
public :: is_host_executor, is_cuda_executor
public :: is_valid_platform
#ifdef DTFFT_WITH_CUDA
public :: dtfft_backend_t
public :: dtfft_get_backend_string
public :: is_valid_gpu_backend, is_backend_pipelined, is_backend_mpi, is_backend_nccl, is_backend_nvshmem
public :: dtfft_stream_t, dtfft_get_cuda_stream
#endif

  integer(int32), parameter, public :: DTFFT_VERSION_MAJOR = CONF_DTFFT_VERSION_MAJOR
    !! dtFFT Major Version
  integer(int32), parameter, public :: DTFFT_VERSION_MINOR = CONF_DTFFT_VERSION_MINOR
    !! dtFFT Minor Version
  integer(int32), parameter, public :: DTFFT_VERSION_PATCH = CONF_DTFFT_VERSION_PATCH
    !! dtFFT Patch Version
  integer(int32), parameter, public :: DTFFT_VERSION_CODE  = CONF_DTFFT_VERSION_CODE
    !! dtFFT Version Code. Can be used in Version comparison

  interface dtfft_get_version
  !! Get dtFFT version
    module procedure :: dtfft_get_version_current  !! Get current version
    module procedure :: dtfft_get_version_required !! Get required version
  end interface dtfft_get_version

!------------------------------------------------------------------------------------------------
! Execute types
!------------------------------------------------------------------------------------------------
  type, bind(C) :: dtfft_execute_t
  !! Type that is used during call to `execute` method
    integer(c_int32_t) :: val !! Internal value
  end type dtfft_execute_t

  type(dtfft_execute_t), parameter, public :: DTFFT_EXECUTE_FORWARD = dtfft_execute_t(CONF_DTFFT_EXECUTE_FORWARD)
    !! Perform XYZ --> YXZ --> ZXY plan execution (Forward)
  type(dtfft_execute_t), parameter, public :: DTFFT_EXECUTE_BACKWARD  = dtfft_execute_t(CONF_DTFFT_EXECUTE_BACKWARD)
    !! Perform ZXY --> YXZ --> XYZ plan execution (Backward)
  type(dtfft_execute_t), parameter :: VALID_EXECUTE_TYPES(*) = [DTFFT_EXECUTE_FORWARD, DTFFT_EXECUTE_BACKWARD]
    !! Valid execute types

!------------------------------------------------------------------------------------------------
! Transpose types
!------------------------------------------------------------------------------------------------
  type, bind(C) :: dtfft_transpose_t
  !! Type that is used during call to [[dtfft_plan_t(type):transpose]] method
    integer(c_int32_t) :: val !! Internal value
  end type dtfft_transpose_t

  type(dtfft_transpose_t), parameter,  public :: DTFFT_TRANSPOSE_X_TO_Y = dtfft_transpose_t(CONF_DTFFT_TRANSPOSE_X_TO_Y)
    !! Perform single transposition, from X aligned to Y aligned
  type(dtfft_transpose_t), parameter,  public :: DTFFT_TRANSPOSE_Y_TO_X = dtfft_transpose_t(CONF_DTFFT_TRANSPOSE_Y_TO_X)
    !! Perform single transposition, from Y aligned to X aligned
  type(dtfft_transpose_t), parameter,  public :: DTFFT_TRANSPOSE_X_TO_Z = dtfft_transpose_t(CONF_DTFFT_TRANSPOSE_X_TO_Z)
    !! Perform single transposition, from X aligned to Z aligned
  type(dtfft_transpose_t), parameter,  public :: DTFFT_TRANSPOSE_Y_TO_Z = dtfft_transpose_t(CONF_DTFFT_TRANSPOSE_Y_TO_Z)
    !! Perform single transposition, from Y aligned to Z aligned
  type(dtfft_transpose_t), parameter,  public :: DTFFT_TRANSPOSE_Z_TO_Y = dtfft_transpose_t(CONF_DTFFT_TRANSPOSE_Z_TO_Y)
    !! Perform single transposition, from Z aligned to Y aligned
  type(dtfft_transpose_t), parameter,  public :: DTFFT_TRANSPOSE_Z_TO_X = dtfft_transpose_t(CONF_DTFFT_TRANSPOSE_Z_TO_X)
    !! Perform single transposition, from Z aligned to X aligned
  type(dtfft_transpose_t), parameter :: VALID_TRANSPOSE_TYPES(*) = [DTFFT_TRANSPOSE_X_TO_Y, DTFFT_TRANSPOSE_Y_TO_X, DTFFT_TRANSPOSE_Y_TO_Z, DTFFT_TRANSPOSE_Z_TO_Y, DTFFT_TRANSPOSE_X_TO_Z, DTFFT_TRANSPOSE_Z_TO_X]
    !! Types of transpose that are valid to pass to `transpose` method
  character(len=*), parameter,  public :: TRANSPOSE_NAMES(-3:3) = ["Z2X", "Z2Y", "Y2X", "NUL", "X2Y", "Y2Z", "X2Z"]
    !! String representation of `dtfft_transpose_t`

!------------------------------------------------------------------------------------------------
! External FFT executor types
!------------------------------------------------------------------------------------------------
  type, bind(C) :: dtfft_executor_t
  !! Type that specifies external FFT executor
    integer(c_int32_t) :: val !! Internal value
  end type dtfft_executor_t

  type(dtfft_executor_t),  parameter,  public :: DTFFT_EXECUTOR_NONE   = dtfft_executor_t(CONF_DTFFT_EXECUTOR_NONE)
    !! Do not setup any executor. If this type is provided, then `execute` method should not be called.
    !! Use `transpose` method instead
  type(dtfft_executor_t),  parameter,  public :: DTFFT_EXECUTOR_FFTW3 = dtfft_executor_t(CONF_DTFFT_EXECUTOR_FFTW3)
    !! FFTW3 executor
  type(dtfft_executor_t),  parameter,  public :: DTFFT_EXECUTOR_MKL   = dtfft_executor_t(CONF_DTFFT_EXECUTOR_MKL)
    !! MKL executor
  type(dtfft_executor_t),  parameter,  public :: DTFFT_EXECUTOR_CUFFT = dtfft_executor_t(CONF_DTFFT_EXECUTOR_CUFFT)
    !! cuFFT GPU executor
  type(dtfft_executor_t),  parameter,  public :: DTFFT_EXECUTOR_VKFFT = dtfft_executor_t(CONF_DTFFT_EXECUTOR_VKFFT)
    !! VkFFT GPU executor
  type(dtfft_executor_t),  parameter  :: VALID_EXECUTORS(*) = [DTFFT_EXECUTOR_NONE    &
#ifdef DTFFT_WITH_FFTW
    ,DTFFT_EXECUTOR_FFTW3                                                             &
#endif
#ifdef DTFFT_WITH_MKL
    ,DTFFT_EXECUTOR_MKL                                                               &
#endif
#ifdef DTFFT_WITH_CUFFT
    ,DTFFT_EXECUTOR_CUFFT                                                             &
#endif
#ifdef DTFFT_WITH_VKFFT
    ,DTFFT_EXECUTOR_VKFFT                                                             &
#endif
  ]
  !! List of valid executors

  type(dtfft_executor_t),  parameter        :: HOST_EXECUTORS(*) = [DTFFT_EXECUTOR_NONE, DTFFT_EXECUTOR_FFTW3, DTFFT_EXECUTOR_MKL]
    !! List of host executors
  type(dtfft_executor_t),  parameter        :: CUDA_EXECUTORS(*) = [DTFFT_EXECUTOR_NONE, DTFFT_EXECUTOR_CUFFT, DTFFT_EXECUTOR_VKFFT]
    !! List of CUDA executors

!------------------------------------------------------------------------------------------------
! FFT Execution directions
!------------------------------------------------------------------------------------------------
  integer(int8),  parameter,  public :: FFT_FORWARD   = CONF_FFT_FORWARD
    !! Forward c2c transform
  integer(int8),  parameter,  public :: FFT_BACKWARD  = CONF_FFT_BACKWARD
    !! Backward c2c transform

!------------------------------------------------------------------------------------------------
! Effort flags.
!------------------------------------------------------------------------------------------------
  type, bind(C) :: dtfft_effort_t
  !! Type that specifies effort that dtFFT should use when creating plan
    integer(c_int32_t) :: val !! Internal value
  end type dtfft_effort_t

  type(dtfft_effort_t), parameter,  public :: DTFFT_ESTIMATE = dtfft_effort_t(CONF_DTFFT_ESTIMATE)
    !! Estimate flag. ``dtFFT`` will use default decomposition provided by MPI_Dims_create
  type(dtfft_effort_t), parameter,  public :: DTFFT_MEASURE  = dtfft_effort_t(CONF_DTFFT_MEASURE)
    !! Measure flag. ``dtFFT`` will run transpose routines to find the best grid decomposition.
    !! Passing this flag and MPI Communicator with Cartesian topology to `plan%create` makes dtFFT do nothing.
  type(dtfft_effort_t), parameter,  public :: DTFFT_PATIENT  = dtfft_effort_t(CONF_DTFFT_PATIENT)
    !! Patient flag. Same as `DTFFT_MEASURE`, but different MPI datatypes will also be tested
  type(dtfft_effort_t), parameter :: VALID_EFFORTS(*) = [DTFFT_ESTIMATE, DTFFT_MEASURE, DTFFT_PATIENT]
    !! Valid effort flags

!------------------------------------------------------------------------------------------------
! Precision flags
!------------------------------------------------------------------------------------------------
  type, bind(C) :: dtfft_precision_t
  !! Type that specifies precision of dtFFT plan
    integer(c_int32_t) :: val !! Internal value
  end type dtfft_precision_t

  type(dtfft_precision_t),  parameter,  public :: DTFFT_SINGLE = dtfft_precision_t(CONF_DTFFT_SINGLE)
    !! Use single precision
  type(dtfft_precision_t),  parameter,  public :: DTFFT_DOUBLE = dtfft_precision_t(CONF_DTFFT_DOUBLE)
    !! Use double precision
  type(dtfft_precision_t),  parameter :: VALID_PRECISIONS(*) = [DTFFT_SINGLE, DTFFT_DOUBLE]
    !! Valid precision flags

!------------------------------------------------------------------------------------------------
! R2R Transform kinds
! This parameters matches FFTW definitions. Hope they will never change there.
!------------------------------------------------------------------------------------------------
  type, bind(C) :: dtfft_r2r_kind_t
  !! Type that specifies various kinds of R2R FFTs
    integer(c_int32_t) :: val !! Internal value
  end type dtfft_r2r_kind_t

  type(dtfft_r2r_kind_t),   parameter,  public :: DTFFT_DCT_1 = dtfft_r2r_kind_t(CONF_DTFFT_DCT_1)
    !! DCT-I (Logical N=2*(n-1), inverse is `DTFFT_DCT_1`)
  type(dtfft_r2r_kind_t),   parameter,  public :: DTFFT_DCT_2 = dtfft_r2r_kind_t(CONF_DTFFT_DCT_2)
    !! DCT-II (Logical N=2*n, inverse is `DTFFT_DCT_3`)
  type(dtfft_r2r_kind_t),   parameter,  public :: DTFFT_DCT_3 = dtfft_r2r_kind_t(CONF_DTFFT_DCT_3)
    !! DCT-III (Logical N=2*n, inverse is `DTFFT_DCT_2`)
  type(dtfft_r2r_kind_t),   parameter,  public :: DTFFT_DCT_4 = dtfft_r2r_kind_t(CONF_DTFFT_DCT_4)
    !! DCT-IV (Logical N=2*n, inverse is `DTFFT_DCT_4`)
  type(dtfft_r2r_kind_t),   parameter,  public :: DTFFT_DST_1 = dtfft_r2r_kind_t(CONF_DTFFT_DST_1)
    !! DST-I (Logical N=2*(n+1), inverse is `DTFFT_DST_1`)
  type(dtfft_r2r_kind_t),   parameter,  public :: DTFFT_DST_2 = dtfft_r2r_kind_t(CONF_DTFFT_DST_2)
    !! DST-II (Logical N=2*n, inverse is `DTFFT_DST_3`)
  type(dtfft_r2r_kind_t),   parameter,  public :: DTFFT_DST_3 = dtfft_r2r_kind_t(CONF_DTFFT_DST_3)
    !! DST-III (Logical N=2*n, inverse is `DTFFT_DST_2`)
  type(dtfft_r2r_kind_t),   parameter,  public :: DTFFT_DST_4 = dtfft_r2r_kind_t(CONF_DTFFT_DST_4)
    !! DST-IV (Logical N=2*n, inverse is `DTFFT_DST_4`)
  type(dtfft_r2r_kind_t),   parameter :: VALID_R2R_KINDS(*) = [DTFFT_DCT_1, DTFFT_DCT_2, DTFFT_DCT_3, DTFFT_DCT_4, DTFFT_DST_1, DTFFT_DST_2, DTFFT_DST_3, DTFFT_DST_4]
    !! Array of valid R2R kinds

public :: operator(==)
  interface operator(==)
    module procedure execute_type_eq    !! Check if two `dtfft_execute_t` are equal
    module procedure transpose_type_eq  !! Check if two `dtfft_transpose_t` are equal
    module procedure executor_eq        !! Check if two `dtfft_executor_t` are equal
    module procedure effort_eq          !! Check if two `dtfft_effort_t` are equal
    module procedure precision_eq       !! Check if two `dtfft_precision_t` are equal
    module procedure r2r_kind_eq        !! Check if two `dtfft_r2r_kind_t` are equal
    module procedure platform_eq        !! Check if two `dtfft_platform_t` are equal
#ifdef DTFFT_WITH_CUDA
    module procedure gpu_backend_eq     !! Check if two `dtfft_backend_t` are equal
#endif
  end interface

public :: operator(/=)
  interface operator(/=)
    module procedure execute_type_ne    !! Check if two `dtfft_execute_t` are not equal
    module procedure transpose_type_ne  !! Check if two `dtfft_transpose_t` are not equal
    module procedure executor_ne        !! Check if two `dtfft_executor_t` are not equal
    module procedure effort_ne          !! Check if two `dtfft_effort_t` are not equal
    module procedure precision_ne       !! Check if two `dtfft_precision_t` are not equal
    module procedure r2r_kind_ne        !! Check if two `dtfft_r2r_kind_t` are not equal
    module procedure platform_ne        !! Check if two `dtfft_platform_t` are not equal
#ifdef DTFFT_WITH_CUDA
    module procedure gpu_backend_ne     !! Check if two `dtfft_backend_t` are not equal
#endif
  end interface

!------------------------------------------------------------------------------------------------
! Storage sizes
!------------------------------------------------------------------------------------------------
  integer(int64), parameter,  public :: DOUBLE_COMPLEX_STORAGE_SIZE   = storage_size((1._real64, 1._real64)) / 8_int64
    !! Number of bytes to store single double precision complex element
  integer(int64), parameter,  public :: COMPLEX_STORAGE_SIZE          = storage_size((1._real32, 1._real32)) / 8_int64
    !! Number of bytes to store single float precision complex element
  integer(int64), parameter,  public :: DOUBLE_STORAGE_SIZE           = storage_size(1._real64) / 8_int64
    !! Number of bytes to store single double precision real element
  integer(int64), parameter,  public :: FLOAT_STORAGE_SIZE            = storage_size(1._real32) / 8_int64
    !! Number of bytes to store single single precision real element


  integer(int8),    parameter :: VALID_DIMENSIONS(*) = [2_int8, 3_int8]
    !! Valid dimensions for `plan.create`
  integer(int32),   parameter :: VALID_COMM_TYPES(*) = [MPI_UNDEFINED, MPI_CART]
    !! Valid communicator types for `plan.create`


  integer(int32), parameter,  public :: COLOR_CREATE        = int(Z'00FAB53C')
    !! Color for `plan.create`
  integer(int32), parameter,  public :: COLOR_EXECUTE       = int(Z'00E25DFC')
    !! Color for `plan.execute`
  integer(int32), parameter,  public :: COLOR_TRANSPOSE     = int(Z'00B175BD')
    !! Color for `plan.transpose`
  integer(int32), parameter,  public :: COLOR_TRANSPOSE_XY  = int(Z'005DFCCA')
    !! Color for `DTFFT_TRANSPOSE_X_TO_Y`
  integer(int32), parameter,  public :: COLOR_TRANSPOSE_YX  = int(Z'0076A797')
    !! Color for `DTFFT_TRANSPOSE_Y_TO_X`
  integer(int32), parameter,  public :: COLOR_TRANSPOSE_YZ  = int(Z'00E3CF9F')
    !! Color for `DTFFT_TRANSPOSE_Y_TO_Z`
  integer(int32), parameter,  public :: COLOR_TRANSPOSE_ZY  = int(Z'008C826A')
    !! Color for `DTFFT_TRANSPOSE_Z_TO_Y`
  integer(int32), parameter,  public :: COLOR_TRANSPOSE_XZ  = int(Z'00546F66')
    !! Color for `DTFFT_TRANSPOSE_X_TO_Z`
  integer(int32), parameter,  public :: COLOR_TRANSPOSE_ZX  = int(Z'007A6D7D')
    !! Color for `DTFFT_TRANSPOSE_Z_TO_X`
  integer(int32), parameter,  public :: COLOR_FFT           = int(Z'00FCD05D')
    !! Color for FFT
  integer(int32), parameter,  public :: COLOR_AUTOTUNE      = int(Z'006075FF')
    !! Color for Autotune
  integer(int32), parameter,  public :: COLOR_AUTOTUNE2     = int(Z'0056E874')
    !! Color for Autotune2
  integer(int32), parameter,  public :: COLOR_DESTROY       = int(Z'00000000')
    !! Color for `plan.destroy`
  integer(int32), parameter,  public :: COLOR_TRANSPOSE_PALLETTE(-3:3) = [COLOR_TRANSPOSE_ZX, COLOR_TRANSPOSE_ZY, COLOR_TRANSPOSE_YX, 0, COLOR_TRANSPOSE_XY, COLOR_TRANSPOSE_YZ, COLOR_TRANSPOSE_XZ]
    !! Color pallete for `plan.transpose`

  integer(int32),  parameter,  public  :: DTFFT_SUCCESS = CONF_DTFFT_SUCCESS
    !! Successful execution
  integer(int32),  parameter,  public  :: DTFFT_ERROR_MPI_FINALIZED = CONF_DTFFT_ERROR_MPI_FINALIZED
    !! MPI_Init is not called or MPI_Finalize has already been called
  integer(int32),  parameter,  public  :: DTFFT_ERROR_PLAN_NOT_CREATED = CONF_DTFFT_ERROR_PLAN_NOT_CREATED
    !! Plan not created
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_TRANSPOSE_TYPE = CONF_DTFFT_ERROR_INVALID_TRANSPOSE_TYPE
    !! Invalid `transpose_type` provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_N_DIMENSIONS = CONF_DTFFT_ERROR_INVALID_N_DIMENSIONS
    !! Invalid Number of dimensions provided. Valid options are 2 and 3
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_DIMENSION_SIZE = CONF_DTFFT_ERROR_INVALID_DIMENSION_SIZE
    !! One or more provided dimension sizes <= 0 
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_COMM_TYPE = CONF_DTFFT_ERROR_INVALID_COMM_TYPE
    !! Invalid communicator type provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_PRECISION = CONF_DTFFT_ERROR_INVALID_PRECISION
    !! Invalid `precision` parameter provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_EFFORT = CONF_DTFFT_ERROR_INVALID_EFFORT_FLAG
    !! Invalid `effort` parameter provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_EXECUTOR = CONF_DTFFT_ERROR_INVALID_EXECUTOR_TYPE
    !! Invalid `executor` parameter provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_COMM_DIMS = CONF_DTFFT_ERROR_INVALID_COMM_DIMS
    !! Number of dimensions in provided Cartesian communicator > Number of dimension passed to `create` subroutine
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_COMM_FAST_DIM = CONF_DTFFT_ERROR_INVALID_COMM_FAST_DIM
    !! Passed Cartesian communicator with number of processes in 1st (fastest varying) dimension > 1
  integer(int32),  parameter,  public  :: DTFFT_ERROR_MISSING_R2R_KINDS = CONF_DTFFT_ERROR_MISSING_R2R_KINDS
    !! For R2R plan, `kinds` parameter must be passed if `executor` != `DTFFT_EXECUTOR_NONE`
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_R2R_KINDS = CONF_DTFFT_ERROR_INVALID_R2R_KINDS
    !! Invalid values detected in `kinds` parameter 
  integer(int32),  parameter,  public  :: DTFFT_ERROR_R2C_TRANSPOSE_PLAN = CONF_DTFFT_ERROR_R2C_TRANSPOSE_PLAN
    !! Transpose plan is not supported in R2C, use R2R or C2C plan instead
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INPLACE_TRANSPOSE = CONF_DTFFT_ERROR_INPLACE_TRANSPOSE
    !! Inplace transpose is not supported
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_AUX = CONF_DTFFT_ERROR_INVALID_AUX
    !! Invalid `aux` buffer provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_DIM = CONF_DTFFT_ERROR_INVALID_DIM
    !! Invalid `dim` passed to `plan.get_pencil`
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_USAGE = CONF_DTFFT_ERROR_INVALID_USAGE
    !! Invalid API Usage.
  integer(int32),  parameter,  public  :: DTFFT_ERROR_PLAN_IS_CREATED = CONF_DTFFT_ERROR_PLAN_IS_CREATED
    !! Trying to create already created plan
  integer(int32),  parameter,  public  :: DTFFT_ERROR_ALLOC_FAILED = CONF_DTFFT_ERROR_ALLOC_FAILED
    !! Internal allocation failed
  integer(int32),  parameter,  public  :: DTFFT_ERROR_FREE_FAILED = CONF_DTFFT_ERROR_FREE_FAILED
    !! Internal memory free failed
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_ALLOC_BYTES = CONF_DTFFT_ERROR_INVALID_ALLOC_BYTES
    !! Invalid `alloc_bytes` provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_DLOPEN_FAILED = CONF_DTFFT_ERROR_DLOPEN_FAILED
    !! dlopen failed
  integer(int32),  parameter,  public  :: DTFFT_ERROR_DLSYM_FAILED = CONF_DTFFT_ERROR_DLSYM_FAILED
    !! dlsym failed
  integer(int32),  parameter,  public  :: DTFFT_ERROR_R2C_TRANSPOSE_CALLED = CONF_DTFFT_ERROR_R2C_TRANSPOSE_CALLED
    !! Calling to `transpose` method for R2C plan is not allowed
  integer(int32),  parameter,  public  :: DTFFT_ERROR_R2R_FFT_NOT_SUPPORTED = CONF_DTFFT_ERROR_R2R_FFT_NOT_SUPPORTED
    !! Selected `executor` do not support R2R FFTs
  integer(int32),  parameter,  public  :: DTFFT_ERROR_GPU_INVALID_STREAM = CONF_DTFFT_ERROR_GPU_INVALID_STREAM
    !! Invalid stream provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_GPU_INVALID_BACKEND = CONF_DTFFT_ERROR_GPU_INVALID_BACKEND
    !! Invalid GPU backend provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_GPU_NOT_SET = CONF_DTFFT_ERROR_GPU_NOT_SET
    !! Multiple MPI Processes located on same host share same GPU which is not supported
  integer(int32),  parameter,  public  :: DTFFT_ERROR_VKFFT_R2R_2D_PLAN = CONF_DTFFT_ERROR_VKFFT_R2R_2D_PLAN
    !! When using R2R FFT and executor type is vkFFT and plan uses Z-slab optimization, it is required that types of R2R transform are same in X and Y directions
  integer(int32),  parameter,  public  :: DTFFT_ERROR_GPU_BACKENDS_DISABLED = CONF_DTFFT_ERROR_GPU_BACKENDS_DISABLED
    !! Passed `effort` ==  `DTFFT_PATIENT` but all GPU Backends has been disabled by `dtfft_config_t` */
  integer(int32),  parameter,  public  :: DTFFT_ERROR_NOT_DEVICE_PTR = CONF_DTFFT_ERROR_NOT_DEVICE_PTR
    !! One of pointers passed to `plan.execute` or `plan.transpose` cannot be accessed from device
  integer(int32),  parameter,  public  :: DTFFT_ERROR_NOT_NVSHMEM_PTR = CONF_DTFFT_ERROR_NOT_NVSHMEM_PTR
    !! One of pointers passed to `plan.execute` or `plan.transpose` is not an `NVSHMEM` pointer
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_PLATFORM = CONF_DTFFT_ERROR_INVALID_PLATFORM
    !! Invalid platform provided
  integer(int32),  parameter,  public  :: DTFFT_ERROR_INVALID_PLATFORM_EXECUTOR_TYPE = CONF_DTFFT_ERROR_INVALID_PLATFORM_EXECUTOR_TYPE
    !! Invalid executor provided for selected platform

  integer(int32),  parameter,  public  :: VARIABLE_NOT_SET = -111
  !! Default value when environ is not set

#ifdef DTFFT_WITH_CUDA

!------------------------------------------------------------------------------------------------
! GPU Backends that are responsible for transfering data across GPUs
!------------------------------------------------------------------------------------------------
  type, bind(C) :: dtfft_backend_t
  !! Type that specifies various GPU Backend present in dtFFT
    integer(c_int32_t) :: val !! Internal value
  end type dtfft_backend_t


  type(dtfft_backend_t),  parameter,  public  :: DTFFT_BACKEND_MPI_DATATYPE = dtfft_backend_t(CONF_DTFFT_BACKEND_MPI_DATATYPE)
    !! Backend that uses MPI datatypes
    !! Not really recommended to use, since it is a million times slower than other backends
    !! Left here just to show how slow MPI Datatypes are for GPU usage
  type(dtfft_backend_t),  parameter,  public  :: DTFFT_BACKEND_MPI_P2P = dtfft_backend_t(CONF_DTFFT_BACKEND_MPI_P2P)
    !! MPI peer-to-peer algorithm
  type(dtfft_backend_t),  parameter,  public  :: DTFFT_BACKEND_MPI_A2A = dtfft_backend_t(CONF_DTFFT_BACKEND_MPI_A2A)
    !! MPI backend using MPI_Alltoallv
  type(dtfft_backend_t),  parameter,  public  :: DTFFT_BACKEND_NCCL = dtfft_backend_t(CONF_DTFFT_BACKEND_NCCL)
    !! NCCL backend
  type(dtfft_backend_t),  parameter,  public  :: DTFFT_BACKEND_MPI_P2P_PIPELINED = dtfft_backend_t(CONF_DTFFT_BACKEND_MPI_P2P_PIPELINED)
    !! MPI peer-to-peer algorithm with overlapping data copying and unpacking
  type(dtfft_backend_t),  parameter,  public  :: DTFFT_BACKEND_NCCL_PIPELINED = dtfft_backend_t(CONF_DTFFT_BACKEND_NCCL_PIPELINED)
    !! NCCL backend with overlapping data copying and unpacking
  type(dtfft_backend_t),  parameter,  public  :: DTFFT_BACKEND_CUFFTMP = dtfft_backend_t(CONF_DTFFT_BACKEND_CUFFTMP)
    !! cuFFTMp backend
  type(dtfft_backend_t),  parameter,  public  :: BACKEND_NOT_SET = dtfft_backend_t(VARIABLE_NOT_SET)
    !! Backend is not used
  type(dtfft_backend_t),  parameter :: PIPELINED_BACKENDS(*) = [DTFFT_BACKEND_MPI_P2P_PIPELINED, DTFFT_BACKEND_NCCL_PIPELINED]
    !! List of pipelined backends
  type(dtfft_backend_t),  parameter :: MPI_BACKENDS(*) = [DTFFT_BACKEND_MPI_P2P, DTFFT_BACKEND_MPI_A2A, DTFFT_BACKEND_MPI_P2P_PIPELINED]
    !! List of MPI backends
  type(dtfft_backend_t),  parameter :: NCCL_BACKENDS(*) = [DTFFT_BACKEND_NCCL, DTFFT_BACKEND_NCCL_PIPELINED]
    !! List of NCCL backends
  type(dtfft_backend_t),  parameter :: NVSHMEM_BACKENDS(*) = [DTFFT_BACKEND_CUFFTMP]
    !! List of NVSHMEM-based backends
  type(dtfft_backend_t),  parameter,  public :: VALID_GPU_BACKENDS(*) = [DTFFT_BACKEND_MPI_DATATYPE         &
                                                                             ,DTFFT_BACKEND_MPI_P2P             &
                                                                             ,DTFFT_BACKEND_MPI_A2A             &
                                                                             ,DTFFT_BACKEND_MPI_P2P_PIPELINED   &
#ifdef DTFFT_WITH_NCCL
                                                                             ,DTFFT_BACKEND_NCCL_PIPELINED      &
                                                                             ,DTFFT_BACKEND_NCCL                &
#endif
#ifdef DTFFT_WITH_NVSHMEM
                                                                             ,DTFFT_BACKEND_CUFFTMP             &
#endif
                                                                             ]
    !! List of valid GPU backends

  type, bind(C) :: dtfft_stream_t
  !! `dtFFT` stream representation.
    type(c_ptr) :: stream !! Actual stream
  end type dtfft_stream_t

  type(dtfft_stream_t), parameter,  public :: NULL_STREAM = dtfft_stream_t(c_null_ptr)

  interface dtfft_stream_t
  !! Creates [[dtfft_stream_t]] from integer(cuda_stream_kind)
    module procedure stream_from_int64
  end interface dtfft_stream_t
#endif

public :: dtfft_platform_t
  type, bind(C) :: dtfft_platform_t
  !! Type that specifies runtime platform, e.g. Host, CUDA, HIP
    integer(c_int32_t) :: val !! Internal value
  end type dtfft_platform_t

  type(dtfft_platform_t), public, parameter :: DTFFT_PLATFORM_HOST = dtfft_platform_t(CONF_DTFFT_PLATFORM_HOST)
    !! Host platform
  type(dtfft_platform_t), public, parameter :: DTFFT_PLATFORM_CUDA = dtfft_platform_t(CONF_DTFFT_PLATFORM_CUDA)
    !! CUDA platform
  type(dtfft_platform_t),         parameter :: VALID_PLATFORMS(*) = [DTFFT_PLATFORM_HOST, DTFFT_PLATFORM_CUDA]
    !! Valid platforms

  ! type(dtfft_platform_t), public, parameter :: DTFFT_PLATFORM_HIP = dtfft_platform_t(3)

  type(dtfft_platform_t), public, parameter :: PLATFORM_NOT_SET = dtfft_platform_t(VARIABLE_NOT_SET)

#define MAKE_EQ_FUN(datatype, name)                         \
  pure elemental function name(left, right) result(res);    \
    type(datatype), intent(in) :: left;                     \
    type(datatype), intent(in) :: right;                    \
    logical :: res;                                         \
    res = left%val == right%val;                            \
  end function name

#define MAKE_NE_FUN(datatype, name)                         \
  pure elemental function name(left, right) result(res);    \
    type(datatype), intent(in) :: left;                     \
    type(datatype), intent(in) :: right;                    \
    logical :: res;                                         \
    res = left%val /= right%val;                            \
  end function name

#define MAKE_VALID_FUN(type, name, valid_values)            \
  pure elemental function name(param) result(res);          \
    type, intent(in)  :: param;                             \
    logical :: res;                                         \
    res = any(param == valid_values);                       \
  end function name

#define MAKE_VALID_FUN_DTYPE(datatype, name, valid_values)  \
  MAKE_VALID_FUN(type(datatype), name, valid_values)

contains

MAKE_EQ_FUN(dtfft_execute_t, execute_type_eq)
MAKE_EQ_FUN(dtfft_transpose_t, transpose_type_eq)
MAKE_EQ_FUN(dtfft_executor_t, executor_eq)
MAKE_EQ_FUN(dtfft_effort_t, effort_eq)
MAKE_EQ_FUN(dtfft_precision_t, precision_eq)
MAKE_EQ_FUN(dtfft_r2r_kind_t, r2r_kind_eq)
MAKE_EQ_FUN(dtfft_platform_t, platform_eq)


MAKE_NE_FUN(dtfft_execute_t, execute_type_ne)
MAKE_NE_FUN(dtfft_transpose_t, transpose_type_ne)
MAKE_NE_FUN(dtfft_executor_t, executor_ne)
MAKE_NE_FUN(dtfft_effort_t, effort_ne)
MAKE_NE_FUN(dtfft_precision_t, precision_ne)
MAKE_NE_FUN(dtfft_r2r_kind_t, r2r_kind_ne)
MAKE_NE_FUN(dtfft_platform_t, platform_ne)

MAKE_VALID_FUN_DTYPE(dtfft_execute_t, is_valid_execute_type, VALID_EXECUTE_TYPES)
MAKE_VALID_FUN_DTYPE(dtfft_transpose_t, is_valid_transpose_type, VALID_TRANSPOSE_TYPES)
MAKE_VALID_FUN_DTYPE(dtfft_executor_t, is_valid_executor, VALID_EXECUTORS)
MAKE_VALID_FUN_DTYPE(dtfft_effort_t, is_valid_effort, VALID_EFFORTS)
MAKE_VALID_FUN_DTYPE(dtfft_precision_t, is_valid_precision, VALID_PRECISIONS)
MAKE_VALID_FUN_DTYPE(dtfft_r2r_kind_t, is_valid_r2r_kind, VALID_R2R_KINDS)
MAKE_VALID_FUN_DTYPE(dtfft_executor_t, is_host_executor, HOST_EXECUTORS)
MAKE_VALID_FUN_DTYPE(dtfft_executor_t, is_cuda_executor, CUDA_EXECUTORS)
MAKE_VALID_FUN_DTYPE(dtfft_platform_t, is_valid_platform, VALID_PLATFORMS)

MAKE_VALID_FUN(integer(int8), is_valid_dimension, VALID_DIMENSIONS)
MAKE_VALID_FUN(integer(int32), is_valid_comm_type, VALID_COMM_TYPES)

  integer(c_int32_t) function dtfft_get_version_current() bind(C)
  !! Returns the current version code
    dtfft_get_version_current = DTFFT_VERSION_CODE
  end function dtfft_get_version_current

  integer(int32) function dtfft_get_version_required(major, minor, patch)
  !! Returns the version code required by the user
    integer(int32), intent(in) :: major !! Major version
    integer(int32), intent(in) :: minor !! Minor version
    integer(int32), intent(in) :: patch !! Patch version

    dtfft_get_version_required = CONF_DTFFT_VERSION(major,minor,patch)
  end function dtfft_get_version_required

  pure function dtfft_get_error_string(error_code) result(error_string)
  !! Gets the string description of an error code
    integer(int32),   intent(in)   :: error_code    !! Error code
    character(len=:), allocatable  :: error_string  !! Error string

    select case (error_code)
    case ( DTFFT_SUCCESS )
      allocate(error_string, source="DTFFT_SUCCESS")
    case ( DTFFT_ERROR_MPI_FINALIZED )
      allocate(error_string, source="MPI_Init is not called or MPI_Finalize has already been called")
    case ( DTFFT_ERROR_PLAN_NOT_CREATED )
      allocate(error_string, source="Plan not created")
    case ( DTFFT_ERROR_INVALID_TRANSPOSE_TYPE )
      allocate(error_string, source="Invalid `transpose_type` provided")
    case ( DTFFT_ERROR_INVALID_N_DIMENSIONS )
      allocate(error_string, source="Invalid Number of dimensions provided. Valid options are 2 and 3")
    case ( DTFFT_ERROR_INVALID_DIMENSION_SIZE )
      allocate(error_string, source="One or more provided dimension sizes <= 0")
    case ( DTFFT_ERROR_INVALID_COMM_TYPE )
      allocate(error_string, source="Invalid communicator type provided")
    case ( DTFFT_ERROR_INVALID_PRECISION )
      allocate(error_string, source="Invalid `precision` parameter provided")
    case ( DTFFT_ERROR_INVALID_EFFORT )
      allocate(error_string, source="Invalid `effort` parameter provided")
    case ( DTFFT_ERROR_INVALID_EXECUTOR )
      allocate(error_string, source="Invalid `executor` parameter provided")
    case ( DTFFT_ERROR_INVALID_COMM_DIMS )
      allocate(error_string, source="Number of dimensions in provided Cartesian communicator > Number of dimension passed to `create` subroutine")
    case ( DTFFT_ERROR_INVALID_COMM_FAST_DIM )
      allocate(error_string, source="Passed Cartesian communicator with number of processes in 1st (fastest varying) dimension > 1")
    case ( DTFFT_ERROR_MISSING_R2R_KINDS )
      allocate(error_string, source="For R2R plan, `kinds` parameter must be passed if `executor` != `DTFFT_EXECUTOR_NONE`")
    case ( DTFFT_ERROR_INVALID_R2R_KINDS )
      allocate(error_string, source="Invalid values detected in `kinds` parameter")
    case ( DTFFT_ERROR_R2C_TRANSPOSE_PLAN )
      allocate(error_string, source="Transpose plan is not supported in R2C, use R2R or C2C plan instead")
    case ( DTFFT_ERROR_INVALID_AUX )
      allocate(error_string, source="Invalid `aux` buffer provided")
    case ( DTFFT_ERROR_INPLACE_TRANSPOSE )
      allocate(error_string, source="Inplace transpose is not supported")
    case ( DTFFT_ERROR_R2R_FFT_NOT_SUPPORTED )
      allocate(error_string, source="Selected `executor` do not support R2R FFTs")
    case ( DTFFT_ERROR_INVALID_DIM )
      allocate(error_string, source="Invalid `dim` passed to `dtfft_get_pencil`")
    case ( DTFFT_ERROR_INVALID_USAGE )
      allocate(error_string, source="Invalid API Usage.")
    case ( DTFFT_ERROR_PLAN_IS_CREATED )
      allocate(error_string, source="Trying to create already created plan")
    case ( DTFFT_ERROR_ALLOC_FAILED )
      allocate(error_string, source="Allocation failed")
    case ( DTFFT_ERROR_FREE_FAILED )
      allocate(error_string, source="Memory free failed")
    case ( DTFFT_ERROR_INVALID_ALLOC_BYTES )
      allocate(error_string, source="Invalid `alloc_bytes` provided")
    case ( DTFFT_ERROR_DLOPEN_FAILED )
      allocate(error_string, source="Failed to open shared library. Set DTFFT_ENABLE_LOG=1 to see the error")
    case ( DTFFT_ERROR_DLSYM_FAILED )
      allocate(error_string, source="Failed to find symbol in shared library. Set DTFFT_ENABLE_LOG=1 to see the error")
    case ( DTFFT_ERROR_R2C_TRANSPOSE_CALLED )
      allocate(error_string, source="Calling to `transpose` method for R2C plan is not allowed")
    case ( DTFFT_ERROR_GPU_INVALID_STREAM )
      allocate(error_string, source="Invalid stream provided")
    case ( DTFFT_ERROR_GPU_INVALID_BACKEND )
      allocate(error_string, source="Invalid GPU backend provided")
    case ( DTFFT_ERROR_GPU_NOT_SET )
      allocate(error_string, source="Multiple MPI Processes located on same host share same GPU which is not supported")
    case ( DTFFT_ERROR_VKFFT_R2R_2D_PLAN )
      allocate(error_string, source="When using R2R FFT and executor type is vkFFT and plan uses Z-slab optimization, it is required that types of R2R transform are same in X and Y directions")
    case ( DTFFT_ERROR_GPU_BACKENDS_DISABLED )
      allocate(error_string, source="Passed `effort` ==  `::DTFFT_PATIENT` but all GPU Backends has been disabled by `dtfft_config_t`")
    case ( DTFFT_ERROR_NOT_DEVICE_PTR )
      allocate(error_string, source="One of pointers passed to `dtfft_execute` or `dtfft_transpose` cannot be accessed from device" )
    case ( DTFFT_ERROR_NOT_NVSHMEM_PTR )
      allocate(error_string, source="One of pointers passed to `dtfft_execute` or `dtfft_transpose` is not an `NVSHMEM` pointer" )
    case ( DTFFT_ERROR_INVALID_PLATFORM )
      allocate(error_string, source="Invalid platform provided")
    case ( DTFFT_ERROR_INVALID_PLATFORM_EXECUTOR_TYPE )
      allocate(error_string, source="Invalid executor provided for selected platform")
    case default
      allocate(error_string, source="Unknown error")
    endselect
  end function dtfft_get_error_string

#ifdef DTFFT_WITH_CUDA
  MAKE_EQ_FUN(dtfft_backend_t, gpu_backend_eq)
  MAKE_NE_FUN(dtfft_backend_t, gpu_backend_ne)
  MAKE_VALID_FUN_DTYPE(dtfft_backend_t, is_valid_gpu_backend, VALID_GPU_BACKENDS)
  MAKE_VALID_FUN_DTYPE(dtfft_backend_t, is_backend_pipelined, PIPELINED_BACKENDS)
  MAKE_VALID_FUN_DTYPE(dtfft_backend_t, is_backend_mpi, MPI_BACKENDS)
  MAKE_VALID_FUN_DTYPE(dtfft_backend_t, is_backend_nccl, NCCL_BACKENDS)
  MAKE_VALID_FUN_DTYPE(dtfft_backend_t, is_backend_nvshmem, NVSHMEM_BACKENDS)

  function dtfft_get_backend_string(backend) result(string)
  !! Gets the string description of a GPU backend
    type(dtfft_backend_t),  intent(in)  :: backend    !! GPU backend
    character(len=:),       allocatable :: string     !! Backend string

    select case ( backend%val )
    case ( DTFFT_BACKEND_MPI_DATATYPE%val )
      allocate(string, source="DTFFT_BACKEND_MPI_DATATYPE")
    case ( DTFFT_BACKEND_MPI_P2P%val )
      allocate(string, source="DTFFT_BACKEND_MPI_P2P")
    case ( DTFFT_BACKEND_MPI_A2A%val )
      allocate(string, source="DTFFT_BACKEND_MPI_A2A")
    case ( DTFFT_BACKEND_NCCL%val )
      allocate(string, source="DTFFT_BACKEND_NCCL")
    case ( DTFFT_BACKEND_CUFFTMP%val )
      allocate(string, source="DTFFT_BACKEND_CUFFTMP")
    case ( DTFFT_BACKEND_MPI_P2P_PIPELINED%val )
      allocate(string, source="DTFFT_BACKEND_MPI_P2P_PIPELINED")
    case ( DTFFT_BACKEND_NCCL_PIPELINED%val )
      allocate(string, source="DTFFT_BACKEND_NCCL_PIPELINED")
    case ( BACKEND_NOT_SET%val )
      allocate(string, source="None" )
    case default
      allocate(string, source="Unknown backend")
    endselect
  end function dtfft_get_backend_string

  function stream_from_int64(cuda_stream) result(stream)
  !! Creates [[dtfft_stream_t]] from integer(cuda_stream_kind)
    integer(int64), intent(in)  :: cuda_stream  !! CUDA stream
    type(dtfft_stream_t)        :: stream       !! dtfft Stream

    stream = transfer(cuda_stream, stream)
  end function stream_from_int64

  function dtfft_get_cuda_stream(stream) result(cuda_stream)
  !! Returns the CUDA stream from [[dtfft_stream_t]]
    type(dtfft_stream_t), intent(in) :: stream      !! dtfft stream
    integer(int64)                   :: cuda_stream !! CUDA stream

    cuda_stream = transfer(stream, int64)
  end function dtfft_get_cuda_stream
#endif
end module dtfft_parameters