!define NO_SWAP_DEVICE
#ifdef NO_SWAP_DEVICE
#define SWAP_DEVICE_RETURN return
#else
#define SWAP_DEVICE_RETURN
#endif
MODULE MODE_OPENACC_SET_DEVICE

#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)
  USE openacc , ONLY : acc_device_kind , acc_device_nvidia, acc_device_host
#endif
  
  IMPLICIT NONE

#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)   
  INTEGER(kind=acc_device_kind) :: mnh_idevice_type_at_init = -1000
  INTEGER(kind=acc_device_kind) :: mnh_idevice_type_current = -1
#endif  

  integer :: iswitch_cpu_gpu = 5
  
CONTAINS
  
  SUBROUTINE MNH_OPENACC_GET_DEVICE_AT_INIT()

#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)      
    USE&
         openacc , ONLY : acc_get_device_type,acc_device_kind
    
    IMPLICIT NONE
    
    INTEGER(kind=acc_device_kind) :: idevice_type

    SWAP_DEVICE_RETURN

    if ( mnh_idevice_type_at_init .EQ. -1000 ) then
       mnh_idevice_type_at_init = acc_get_device_type()
       mnh_idevice_type_current = mnh_idevice_type_at_init
       print*,'mnh_idevice_type_at_init=',mnh_idevice_type_at_init
    end if
#endif
    
  END SUBROUTINE MNH_OPENACC_GET_DEVICE_AT_INIT
  
  SUBROUTINE MNH_OPENACC_GET_DEVICE()

#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)    
    USE&
         openacc , ONLY : acc_get_device_type,acc_device_kind
    
    IMPLICIT NONE
    
    INTEGER(kind=acc_device_kind) :: idevice_type

    SWAP_DEVICE_RETURN
    
    idevice_type = acc_get_device_type()
    mnh_idevice_type_current = idevice_type
    print*,'idevice_type=',idevice_type
#endif
    
  END SUBROUTINE MNH_OPENACC_GET_DEVICE
  
  SUBROUTINE MNH_OPENACC_SET_DEVICE_HOST()

#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)    
    USE&
         openacc , ONLY : acc_set_device_type,acc_device_host,acc_get_device_type
    
    IMPLICIT NONE

    SWAP_DEVICE_RETURN

    call acc_set_device_type(acc_device_host)
    mnh_idevice_type_current = acc_device_host
    
#endif
    
  END SUBROUTINE MNH_OPENACC_SET_DEVICE_HOST
  
  SUBROUTINE MNH_OPENACC_SET_DEVICE_NVIDIA()

#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)    
    USE&
         openacc , ONLY : acc_set_device_type,acc_device_nvidia,acc_get_device_type
    
    IMPLICIT NONE

    SWAP_DEVICE_RETURN
    
    call acc_set_device_type(acc_device_nvidia)
    mnh_idevice_type_current = acc_device_nvidia
#endif
    
  END SUBROUTINE MNH_OPENACC_SET_DEVICE_NVIDIA

 SUBROUTINE MNH_OPENACC_SET_DEVICE_DEFAULT()

#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)
    USE&
         openacc , ONLY : acc_set_device_type,acc_device_nvidia,acc_get_device_type
    
    IMPLICIT NONE

    SWAP_DEVICE_RETURN

    call acc_set_device_type(mnh_idevice_type_at_init)
    mnh_idevice_type_current = mnh_idevice_type_at_init
#endif
   
  END SUBROUTINE MNH_OPENACC_SET_DEVICE_DEFAULT

END MODULE MODE_OPENACC_SET_DEVICE