cuFFT using OpenACC

! This program is received from Bharatkumar Sharma, NVIDIA, Bangalore, India.

module cufft

  INTERFACE

    subroutine launchcufft(data, n, stream) BIND (C, NAME='launchCUFFT')

      USE ISO_C_BINDING

      USE openacc

      implicit none

      type (C_PTR), value :: data

      integer (C_INT), value :: n

      integer(acc_handle_kind), value :: stream

    end subroutine

  END INTERFACE

end module cufft

program fft

    USE ISO_C_BINDING

    USE cufft

    USE openacc

    IMPLICIT NONE

    INTEGER, PARAMETER :: n = 256

    COMPLEX (C_FLOAT_COMPLEX) :: data(n)

    INTEGER (C_INT):: i

    INTEGER :: max_id,istat

    integer(acc_handle_kind) :: stream

    ! Initialize interleaved input data on host

    REAL :: w = 7.0

    REAL :: x

    REAL, PARAMETER :: PI = 3.1415927

    do i=1,n

        x = (i-1.0)/(n-1.0);

        data(i) = CMPLX(COS(2.0*PI*w*x),0.0)

    enddo

    ! Copy data to device at start of region and back to host and end of region

    !$acc data copy(data)

        ! Inside this region the device data pointer will be used

        !$acc host_data use_device(data)

        stream = acc_get_cuda_stream(acc_async_sync)

        call launchcufft(C_LOC(data), n, stream)

        !$acc end host_data

    !$acc end data

    ! Find the frequency

    max_id = 1

    do i=1,n/2

        if (REAL(data(i)) .gt. REAL(data(max_id))) then

            max_id = i-1

        endif

    enddo

    print *, "frequency:", max_id

end program fft