!HANDLE FFTS
module wei_fft_mkl_mod
  use wei_step_mod
#ifdef INTEL_MKL
  use  MKL_DFTI
   type(dfti_descriptor),pointer,private :: dfti(:)


contains

  subroutine weifft_mkl_init_ser(wfld)
    complex      :: wfld(:,:,:,:,:)
    integer      :: n(4),ith,ierr,i
#ifdef DEBUG
    write(0,*) "IN FFT MKL INIT SER"
#endif

   allocate(dfti(size(wfld,5)))

   n(1)=size(wfld,1);n(2)=size(wfld,2);n(3)=size(wfld,3);n(4)=size(wfld,4)

   
   do i=1,size(wfld,5)
     ierr= dfticreatedescriptor(dfti(i),dfti_single,DFTI_COMPLEX,4,n)
   end do

#ifdef DEBUG
    write(0,*) "OUT FFT MKL INIT SER"
#endif

  end subroutine 


  subroutine weifft_mkl_init_par(wfld,step)
    type(westep) :: step
    complex      :: wfld(:,:,:,:,:)
    integer      :: n(4),ith,ierr
#ifdef DEBUG
    write(0,*) "IN FFT MKL INIT PAR"
#endif


   step%dffti=step%dffti(step%ithread)

#ifdef DEBUG
    write(0,*) "OUT FFT MKL INIT PAR"
#endif

  end subroutine 





  !! forward FFT
  subroutine wei_ffft_mkl(data,step)
    complex, dimension(:,:,:,:,:) :: data
    type(westep)                  :: step
#ifdef DEBUG
    write(0,*) "IN FORWARD FFT MKL"
#endif
    call weifft_internal(step%dffti,step%iws,size(data)/size(data,5),size(data,5),data)
#ifdef DEBUG
    write(0,*) "OUT FORWARD FFT MKL"
#endif
  end subroutine


  !! inverse FFT
  subroutine wei_ifft_mkl(data,step)
    complex, dimension(:,:,:,:,:) :: data
    type(westep)                  :: step
#ifdef DEBUG
    write(0,*) "IN INVERSE FFT MKL"
#endif
    call weiift_internal(step%dffti,step%iws,size(data)/size(data,5),size(data,5),data)
#ifdef DEBUG
    write(0,*) "OUT INVERSE FFT MKL"
#endif
  end subroutine

  subroutine weifft_internal(dfft,iws,n,nw,data)
    type(dfft_descriptor)   :: dfft
    integer, intent(in) :: iws, n,nw
    complex, dimension(n,nw):: data
    integer :: imx,imy,iplan,nd(4),i1,i2,i3,i4,ierr
#ifdef DEBUG
    write(0,*) "IN FORWARD INTERNAL FFT MKL"
#endif
    ierr=dfticomputeforward(dfti%dft_d,data(:,iws))
#ifdef DEBUG
    write(0,*) "IN FORWARD INTERNAL FFT MKL"
#endif
  end subroutine

  subroutine weiift_internal(dfft,iws,n,nw,data)
    integer, intent(in) :: iws, n,nw
    type(dfft_descriptor)   :: dfft
    complex, dimension(n,nw):: data
    integer :: imx,imy,iplan,nd(4),i1,i2,i3,i4,ierr
#ifdef DEBUG
    write(0,*) "IN INVERSE INTERNAL FFT MKL"
#endif
    ierr=dfticomputebackward(dfti%dft_d,data(:,iws))
#ifdef DEBUG
    write(0,*) "IN INVERSE INTERNAL FFT MKL"
#endif
  end subroutine
#endif 

end module 
