!
! Copyright (C) 2022, MaX CoE
! Distributed under the MIT License 
! (license terms are at http://opensource.org/licenses/MIT).
!
!--
!
!
! Utility functions to perform device-host memcpy
! using CUDA-Fortran, OpenACC or OpenMP Offload
!
!==================================================================
!==================================================================
! *DO NOT EDIT*: automatically generated from device_memcpy_d2h.jf90
!==================================================================
!==================================================================
!
#include<devxlib_macros.h>
#include<devxlib_defs.h>
!
!=======================================
!
! Note about dimensions:
! The lower bound of the assumed shape array passed to the subroutine is 1
! lbound and range instead refer to the indexing in the parent caller.
!
submodule (devxlib_memcpy) devxlib_memcpy_d2h

   implicit none

   contains
      module subroutine sp_devxlib_memcpy_d2h_r1d(array_out, array_in, &
                                             range1, lbound1  )
         implicit none
         !
         real(real32), intent(inout) :: array_out(:)
         real(real32) DEV_ATTR, intent(in)    :: array_in(:)
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy( array_out(d1_start), array_in(d1_start), d1_size, cudaMemcpyDeviceToHost )
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_r1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#else
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r1d
!
      module subroutine sp_devxlib_memcpy_d2h_r2d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         real(real32), intent(inout) :: array_out(:,:)
         real(real32) DEV_ATTR, intent(in)    :: array_in(:,:)
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy2D( array_out(d1_start, d2_start) , d1_ld, array_in(d1_start, d2_start), d1_ld, d1_size, d2_size )
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_r2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r2d
!
      module subroutine sp_devxlib_memcpy_d2h_r3d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         real(real32), intent(inout) :: array_out(:,:,:)
         real(real32) DEV_ATTR, intent(in)    :: array_in(:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_r3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r3d
!
      module subroutine sp_devxlib_memcpy_d2h_r4d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         real(real32), intent(inout) :: array_out(:,:,:,:)
         real(real32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_r4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r4d
!
      module subroutine sp_devxlib_memcpy_d2h_r5d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         real(real32), intent(inout) :: array_out(:,:,:,:,:)
         real(real32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_r5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r5d
!
      module subroutine sp_devxlib_memcpy_d2h_r6d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         real(real32), intent(inout) :: array_out(:,:,:,:,:,:)
         real(real32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_r6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r6d
!
      module subroutine dp_devxlib_memcpy_d2h_r1d(array_out, array_in, &
                                             range1, lbound1  )
         implicit none
         !
         real(real64), intent(inout) :: array_out(:)
         real(real64) DEV_ATTR, intent(in)    :: array_in(:)
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy( array_out(d1_start), array_in(d1_start), d1_size, cudaMemcpyDeviceToHost )
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_r1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#else
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r1d
!
      module subroutine dp_devxlib_memcpy_d2h_r2d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         real(real64), intent(inout) :: array_out(:,:)
         real(real64) DEV_ATTR, intent(in)    :: array_in(:,:)
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy2D( array_out(d1_start, d2_start) , d1_ld, array_in(d1_start, d2_start), d1_ld, d1_size, d2_size )
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_r2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r2d
!
      module subroutine dp_devxlib_memcpy_d2h_r3d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         real(real64), intent(inout) :: array_out(:,:,:)
         real(real64) DEV_ATTR, intent(in)    :: array_in(:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_r3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r3d
!
      module subroutine dp_devxlib_memcpy_d2h_r4d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         real(real64), intent(inout) :: array_out(:,:,:,:)
         real(real64) DEV_ATTR, intent(in)    :: array_in(:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_r4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r4d
!
      module subroutine dp_devxlib_memcpy_d2h_r5d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         real(real64), intent(inout) :: array_out(:,:,:,:,:)
         real(real64) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_r5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r5d
!
      module subroutine dp_devxlib_memcpy_d2h_r6d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         real(real64), intent(inout) :: array_out(:,:,:,:,:,:)
         real(real64) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_r6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r6d
!
      module subroutine sp_devxlib_memcpy_d2h_c1d(array_out, array_in, &
                                             range1, lbound1  )
         implicit none
         !
         complex(real32), intent(inout) :: array_out(:)
         complex(real32) DEV_ATTR, intent(in)    :: array_in(:)
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy( array_out(d1_start), array_in(d1_start), d1_size, cudaMemcpyDeviceToHost )
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_c1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#else
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c1d
!
      module subroutine sp_devxlib_memcpy_d2h_c2d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         complex(real32), intent(inout) :: array_out(:,:)
         complex(real32) DEV_ATTR, intent(in)    :: array_in(:,:)
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy2D( array_out(d1_start, d2_start) , d1_ld, array_in(d1_start, d2_start), d1_ld, d1_size, d2_size )
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_c2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c2d
!
      module subroutine sp_devxlib_memcpy_d2h_c3d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         complex(real32), intent(inout) :: array_out(:,:,:)
         complex(real32) DEV_ATTR, intent(in)    :: array_in(:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_c3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c3d
!
      module subroutine sp_devxlib_memcpy_d2h_c4d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         complex(real32), intent(inout) :: array_out(:,:,:,:)
         complex(real32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_c4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c4d
!
      module subroutine sp_devxlib_memcpy_d2h_c5d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         complex(real32), intent(inout) :: array_out(:,:,:,:,:)
         complex(real32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_c5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c5d
!
      module subroutine sp_devxlib_memcpy_d2h_c6d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         complex(real32), intent(inout) :: array_out(:,:,:,:,:,:)
         complex(real32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_c6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c6d
!
      module subroutine dp_devxlib_memcpy_d2h_c1d(array_out, array_in, &
                                             range1, lbound1  )
         implicit none
         !
         complex(real64), intent(inout) :: array_out(:)
         complex(real64) DEV_ATTR, intent(in)    :: array_in(:)
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy( array_out(d1_start), array_in(d1_start), d1_size, cudaMemcpyDeviceToHost )
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_c1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#else
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c1d
!
      module subroutine dp_devxlib_memcpy_d2h_c2d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         complex(real64), intent(inout) :: array_out(:,:)
         complex(real64) DEV_ATTR, intent(in)    :: array_in(:,:)
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy2D( array_out(d1_start, d2_start) , d1_ld, array_in(d1_start, d2_start), d1_ld, d1_size, d2_size )
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_c2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c2d
!
      module subroutine dp_devxlib_memcpy_d2h_c3d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         complex(real64), intent(inout) :: array_out(:,:,:)
         complex(real64) DEV_ATTR, intent(in)    :: array_in(:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_c3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c3d
!
      module subroutine dp_devxlib_memcpy_d2h_c4d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         complex(real64), intent(inout) :: array_out(:,:,:,:)
         complex(real64) DEV_ATTR, intent(in)    :: array_in(:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_c4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c4d
!
      module subroutine dp_devxlib_memcpy_d2h_c5d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         complex(real64), intent(inout) :: array_out(:,:,:,:,:)
         complex(real64) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_c5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c5d
!
      module subroutine dp_devxlib_memcpy_d2h_c6d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         complex(real64), intent(inout) :: array_out(:,:,:,:,:,:)
         complex(real64) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_c6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c6d
!
      module subroutine i4_devxlib_memcpy_d2h_i1d(array_out, array_in, &
                                             range1, lbound1  )
         implicit none
         !
         integer(int32), intent(inout) :: array_out(:)
         integer(int32) DEV_ATTR, intent(in)    :: array_in(:)
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy( array_out(d1_start), array_in(d1_start), d1_size, cudaMemcpyDeviceToHost )
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_i1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#else
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i1d
!
      module subroutine i4_devxlib_memcpy_d2h_i2d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         integer(int32), intent(inout) :: array_out(:,:)
         integer(int32) DEV_ATTR, intent(in)    :: array_in(:,:)
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy2D( array_out(d1_start, d2_start) , d1_ld, array_in(d1_start, d2_start), d1_ld, d1_size, d2_size )
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_i2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i2d
!
      module subroutine i4_devxlib_memcpy_d2h_i3d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         integer(int32), intent(inout) :: array_out(:,:,:)
         integer(int32) DEV_ATTR, intent(in)    :: array_in(:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_i3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i3d
!
      module subroutine i4_devxlib_memcpy_d2h_i4d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         integer(int32), intent(inout) :: array_out(:,:,:,:)
         integer(int32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_i4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i4d
!
      module subroutine i4_devxlib_memcpy_d2h_i5d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         integer(int32), intent(inout) :: array_out(:,:,:,:,:)
         integer(int32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_i5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i5d
!
      module subroutine i4_devxlib_memcpy_d2h_i6d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         integer(int32), intent(inout) :: array_out(:,:,:,:,:,:)
         integer(int32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_i6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i6d
!
      module subroutine i8_devxlib_memcpy_d2h_i1d(array_out, array_in, &
                                             range1, lbound1  )
         implicit none
         !
         integer(int64), intent(inout) :: array_out(:)
         integer(int64) DEV_ATTR, intent(in)    :: array_in(:)
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy( array_out(d1_start), array_in(d1_start), d1_size, cudaMemcpyDeviceToHost )
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_i1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#else
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i1d
!
      module subroutine i8_devxlib_memcpy_d2h_i2d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         integer(int64), intent(inout) :: array_out(:,:)
         integer(int64) DEV_ATTR, intent(in)    :: array_in(:,:)
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy2D( array_out(d1_start, d2_start) , d1_ld, array_in(d1_start, d2_start), d1_ld, d1_size, d2_size )
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_i2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i2d
!
      module subroutine i8_devxlib_memcpy_d2h_i3d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         integer(int64), intent(inout) :: array_out(:,:,:)
         integer(int64) DEV_ATTR, intent(in)    :: array_in(:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_i3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i3d
!
      module subroutine i8_devxlib_memcpy_d2h_i4d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         integer(int64), intent(inout) :: array_out(:,:,:,:)
         integer(int64) DEV_ATTR, intent(in)    :: array_in(:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_i4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i4d
!
      module subroutine i8_devxlib_memcpy_d2h_i5d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         integer(int64), intent(inout) :: array_out(:,:,:,:,:)
         integer(int64) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_i5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i5d
!
      module subroutine i8_devxlib_memcpy_d2h_i6d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         integer(int64), intent(inout) :: array_out(:,:,:,:,:,:)
         integer(int64) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_i6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i6d
!
      module subroutine l4_devxlib_memcpy_d2h_l1d(array_out, array_in, &
                                             range1, lbound1  )
         implicit none
         !
         logical(int32), intent(inout) :: array_out(:)
         logical(int32) DEV_ATTR, intent(in)    :: array_in(:)
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy( array_out(d1_start), array_in(d1_start), d1_size, cudaMemcpyDeviceToHost )
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_l1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#else
         array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l1d
!
      module subroutine l4_devxlib_memcpy_d2h_l2d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         logical(int32), intent(inout) :: array_out(:,:)
         logical(int32) DEV_ATTR, intent(in)    :: array_in(:,:)
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy2D( array_out(d1_start, d2_start) , d1_ld, array_in(d1_start, d2_start), d1_ld, d1_size, d2_size )
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_l2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l2d
!
      module subroutine l4_devxlib_memcpy_d2h_l3d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         logical(int32), intent(inout) :: array_out(:,:,:)
         logical(int32) DEV_ATTR, intent(in)    :: array_in(:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_l3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l3d
!
      module subroutine l4_devxlib_memcpy_d2h_l4d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         logical(int32), intent(inout) :: array_out(:,:,:,:)
         logical(int32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_l4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l4d
!
      module subroutine l4_devxlib_memcpy_d2h_l5d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         logical(int32), intent(inout) :: array_out(:,:,:,:,:)
         logical(int32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_l5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l5d
!
      module subroutine l4_devxlib_memcpy_d2h_l6d(array_out, array_in, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         logical(int32), intent(inout) :: array_out(:,:,:,:,:,:)
         logical(int32) DEV_ATTR, intent(in)    :: array_in(:,:,:,:,:,:)
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
         !
#if defined __DXL_CUDAF
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_l6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) wait
         !DEV_OMPGPU target update from(array_in)
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l6d
!
      module subroutine sp_devxlib_memcpy_d2h_async_r1d(array_out, array_in, async_id, &
                                             range1, lbound1  )
         implicit none
         !
         real(real32), target, intent(inout)       :: array_out(:)
         real(real32), target, intent(inout) DEV_ATTR :: array_in(:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_r1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start))
         ptr2=c_loc( array_in(d1_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
         endif
#else
         array_out(d1_start:d1_end) = &
                 array_in(d1_start:d1_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_r1d
!
      module subroutine sp_devxlib_memcpy_d2h_async_r2d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         real(real32), target, intent(inout)       :: array_out(:,:)
         real(real32), target, intent(inout) DEV_ATTR :: array_in(:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_r2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start))
         ptr2=c_loc( array_in(d1_start,d2_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_r2d
!
      module subroutine sp_devxlib_memcpy_d2h_async_r3d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         real(real32), target, intent(inout)       :: array_out(:,:,:)
         real(real32), target, intent(inout) DEV_ATTR :: array_in(:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_r3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_r3d
!
      module subroutine sp_devxlib_memcpy_d2h_async_r4d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         real(real32), target, intent(inout)       :: array_out(:,:,:,:)
         real(real32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_r4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_r4d
!
      module subroutine sp_devxlib_memcpy_d2h_async_r5d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         real(real32), target, intent(inout)       :: array_out(:,:,:,:,:)
         real(real32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_r5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_r5d
!
      module subroutine sp_devxlib_memcpy_d2h_async_r6d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         real(real32), target, intent(inout)       :: array_out(:,:,:,:,:,:)
         real(real32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size*d6_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_r6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_r6d
!
      module subroutine dp_devxlib_memcpy_d2h_async_r1d(array_out, array_in, async_id, &
                                             range1, lbound1  )
         implicit none
         !
         real(real64), target, intent(inout)       :: array_out(:)
         real(real64), target, intent(inout) DEV_ATTR :: array_in(:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_r1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start))
         ptr2=c_loc( array_in(d1_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
         endif
#else
         array_out(d1_start:d1_end) = &
                 array_in(d1_start:d1_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_r1d
!
      module subroutine dp_devxlib_memcpy_d2h_async_r2d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         real(real64), target, intent(inout)       :: array_out(:,:)
         real(real64), target, intent(inout) DEV_ATTR :: array_in(:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_r2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start))
         ptr2=c_loc( array_in(d1_start,d2_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_r2d
!
      module subroutine dp_devxlib_memcpy_d2h_async_r3d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         real(real64), target, intent(inout)       :: array_out(:,:,:)
         real(real64), target, intent(inout) DEV_ATTR :: array_in(:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_r3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_r3d
!
      module subroutine dp_devxlib_memcpy_d2h_async_r4d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         real(real64), target, intent(inout)       :: array_out(:,:,:,:)
         real(real64), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_r4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_r4d
!
      module subroutine dp_devxlib_memcpy_d2h_async_r5d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         real(real64), target, intent(inout)       :: array_out(:,:,:,:,:)
         real(real64), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_r5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_r5d
!
      module subroutine dp_devxlib_memcpy_d2h_async_r6d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         real(real64), target, intent(inout)       :: array_out(:,:,:,:,:,:)
         real(real64), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size*d6_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_r6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_r6d
!
      module subroutine sp_devxlib_memcpy_d2h_async_c1d(array_out, array_in, async_id, &
                                             range1, lbound1  )
         implicit none
         !
         complex(real32), target, intent(inout)       :: array_out(:)
         complex(real32), target, intent(inout) DEV_ATTR :: array_in(:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_c1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start))
         ptr2=c_loc( array_in(d1_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
         endif
#else
         array_out(d1_start:d1_end) = &
                 array_in(d1_start:d1_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_c1d
!
      module subroutine sp_devxlib_memcpy_d2h_async_c2d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         complex(real32), target, intent(inout)       :: array_out(:,:)
         complex(real32), target, intent(inout) DEV_ATTR :: array_in(:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_c2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start))
         ptr2=c_loc( array_in(d1_start,d2_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_c2d
!
      module subroutine sp_devxlib_memcpy_d2h_async_c3d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         complex(real32), target, intent(inout)       :: array_out(:,:,:)
         complex(real32), target, intent(inout) DEV_ATTR :: array_in(:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_c3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_c3d
!
      module subroutine sp_devxlib_memcpy_d2h_async_c4d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         complex(real32), target, intent(inout)       :: array_out(:,:,:,:)
         complex(real32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_c4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_c4d
!
      module subroutine sp_devxlib_memcpy_d2h_async_c5d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         complex(real32), target, intent(inout)       :: array_out(:,:,:,:,:)
         complex(real32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_c5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_c5d
!
      module subroutine sp_devxlib_memcpy_d2h_async_c6d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         complex(real32), target, intent(inout)       :: array_out(:,:,:,:,:,:)
         complex(real32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size*d6_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("sp_memcpy_d2h_async_c6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_async_c6d
!
      module subroutine dp_devxlib_memcpy_d2h_async_c1d(array_out, array_in, async_id, &
                                             range1, lbound1  )
         implicit none
         !
         complex(real64), target, intent(inout)       :: array_out(:)
         complex(real64), target, intent(inout) DEV_ATTR :: array_in(:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_c1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start))
         ptr2=c_loc( array_in(d1_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
         endif
#else
         array_out(d1_start:d1_end) = &
                 array_in(d1_start:d1_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_c1d
!
      module subroutine dp_devxlib_memcpy_d2h_async_c2d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         complex(real64), target, intent(inout)       :: array_out(:,:)
         complex(real64), target, intent(inout) DEV_ATTR :: array_in(:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_c2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start))
         ptr2=c_loc( array_in(d1_start,d2_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_c2d
!
      module subroutine dp_devxlib_memcpy_d2h_async_c3d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         complex(real64), target, intent(inout)       :: array_out(:,:,:)
         complex(real64), target, intent(inout) DEV_ATTR :: array_in(:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_c3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_c3d
!
      module subroutine dp_devxlib_memcpy_d2h_async_c4d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         complex(real64), target, intent(inout)       :: array_out(:,:,:,:)
         complex(real64), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_c4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_c4d
!
      module subroutine dp_devxlib_memcpy_d2h_async_c5d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         complex(real64), target, intent(inout)       :: array_out(:,:,:,:,:)
         complex(real64), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_c5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_c5d
!
      module subroutine dp_devxlib_memcpy_d2h_async_c6d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         complex(real64), target, intent(inout)       :: array_out(:,:,:,:,:,:)
         complex(real64), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size*d6_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("dp_memcpy_d2h_async_c6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_async_c6d
!
      module subroutine i4_devxlib_memcpy_d2h_async_i1d(array_out, array_in, async_id, &
                                             range1, lbound1  )
         implicit none
         !
         integer(int32), target, intent(inout)       :: array_out(:)
         integer(int32), target, intent(inout) DEV_ATTR :: array_in(:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_async_i1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start))
         ptr2=c_loc( array_in(d1_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
         endif
#else
         array_out(d1_start:d1_end) = &
                 array_in(d1_start:d1_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_async_i1d
!
      module subroutine i4_devxlib_memcpy_d2h_async_i2d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         integer(int32), target, intent(inout)       :: array_out(:,:)
         integer(int32), target, intent(inout) DEV_ATTR :: array_in(:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_async_i2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start))
         ptr2=c_loc( array_in(d1_start,d2_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_async_i2d
!
      module subroutine i4_devxlib_memcpy_d2h_async_i3d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         integer(int32), target, intent(inout)       :: array_out(:,:,:)
         integer(int32), target, intent(inout) DEV_ATTR :: array_in(:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_async_i3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_async_i3d
!
      module subroutine i4_devxlib_memcpy_d2h_async_i4d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         integer(int32), target, intent(inout)       :: array_out(:,:,:,:)
         integer(int32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_async_i4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_async_i4d
!
      module subroutine i4_devxlib_memcpy_d2h_async_i5d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         integer(int32), target, intent(inout)       :: array_out(:,:,:,:,:)
         integer(int32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_async_i5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_async_i5d
!
      module subroutine i4_devxlib_memcpy_d2h_async_i6d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         integer(int32), target, intent(inout)       :: array_out(:,:,:,:,:,:)
         integer(int32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size*d6_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i4_memcpy_d2h_async_i6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_async_i6d
!
      module subroutine i8_devxlib_memcpy_d2h_async_i1d(array_out, array_in, async_id, &
                                             range1, lbound1  )
         implicit none
         !
         integer(int64), target, intent(inout)       :: array_out(:)
         integer(int64), target, intent(inout) DEV_ATTR :: array_in(:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_async_i1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start))
         ptr2=c_loc( array_in(d1_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
         endif
#else
         array_out(d1_start:d1_end) = &
                 array_in(d1_start:d1_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_async_i1d
!
      module subroutine i8_devxlib_memcpy_d2h_async_i2d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         integer(int64), target, intent(inout)       :: array_out(:,:)
         integer(int64), target, intent(inout) DEV_ATTR :: array_in(:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_async_i2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start))
         ptr2=c_loc( array_in(d1_start,d2_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_async_i2d
!
      module subroutine i8_devxlib_memcpy_d2h_async_i3d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         integer(int64), target, intent(inout)       :: array_out(:,:,:)
         integer(int64), target, intent(inout) DEV_ATTR :: array_in(:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_async_i3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_async_i3d
!
      module subroutine i8_devxlib_memcpy_d2h_async_i4d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         integer(int64), target, intent(inout)       :: array_out(:,:,:,:)
         integer(int64), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_async_i4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_async_i4d
!
      module subroutine i8_devxlib_memcpy_d2h_async_i5d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         integer(int64), target, intent(inout)       :: array_out(:,:,:,:,:)
         integer(int64), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_async_i5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_async_i5d
!
      module subroutine i8_devxlib_memcpy_d2h_async_i6d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         integer(int64), target, intent(inout)       :: array_out(:,:,:,:,:,:)
         integer(int64), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size*d6_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("i8_memcpy_d2h_async_i6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_async_i6d
!
      module subroutine l4_devxlib_memcpy_d2h_async_l1d(array_out, array_in, async_id, &
                                             range1, lbound1  )
         implicit none
         !
         logical(int32), target, intent(inout)       :: array_out(:)
         logical(int32), target, intent(inout) DEV_ATTR :: array_in(:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2)
         integer, optional, intent(in) ::  lbound1
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_async_l1d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start))
         ptr2=c_loc( array_in(d1_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end) = &
                   array_in(d1_start:d1_end)
         endif
#else
         array_out(d1_start:d1_end) = &
                 array_in(d1_start:d1_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_async_l1d
!
      module subroutine l4_devxlib_memcpy_d2h_async_l2d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2  )
         implicit none
         !
         logical(int32), target, intent(inout)       :: array_out(:,:)
         logical(int32), target, intent(inout) DEV_ATTR :: array_in(:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2)
         integer, optional, intent(in) ::  lbound1, lbound2
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_async_l2d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start))
         ptr2=c_loc( array_in(d1_start,d2_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_async_l2d
!
      module subroutine l4_devxlib_memcpy_d2h_async_l3d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3  )
         implicit none
         !
         logical(int32), target, intent(inout)       :: array_out(:,:,:)
         logical(int32), target, intent(inout) DEV_ATTR :: array_in(:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_async_l3d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_async_l3d
!
      module subroutine l4_devxlib_memcpy_d2h_async_l4d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4  )
         implicit none
         !
         logical(int32), target, intent(inout)       :: array_out(:,:,:,:)
         logical(int32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_async_l4d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_async_l4d
!
      module subroutine l4_devxlib_memcpy_d2h_async_l5d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5  )
         implicit none
         !
         logical(int32), target, intent(inout)       :: array_out(:,:,:,:,:)
         logical(int32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_async_l5d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_async_l5d
!
      module subroutine l4_devxlib_memcpy_d2h_async_l6d(array_out, array_in, async_id, &
                                             range1, lbound1 , &
                                             range2, lbound2 , &
                                             range3, lbound3 , &
                                             range4, lbound4 , &
                                             range5, lbound5 , &
                                             range6, lbound6  )
         implicit none
         !
         logical(int32), target, intent(inout)       :: array_out(:,:,:,:,:,:)
         logical(int32), target, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         integer(kind=dxl_async_kind), intent(in) :: async_id
         integer, optional, intent(in) ::  range1(2), range2(2), range3(2), range4(2), range5(2), range6(2)
         integer, optional, intent(in) ::  lbound1, lbound2, lbound3, lbound4, lbound5, lbound6
         type(c_ptr) :: ptr1,ptr2
         integer :: ierr = 0
         integer :: d1_start, d1_end, d1_size, d1_ld
         integer :: lbound1_, range1_(2)
         integer :: d2_start, d2_end, d2_size, d2_ld
         integer :: lbound2_, range2_(2)
         integer :: d3_start, d3_end, d3_size, d3_ld
         integer :: lbound3_, range3_(2)
         integer :: d4_start, d4_end, d4_size, d4_ld
         integer :: lbound4_, range4_(2)
         integer :: d5_start, d5_end, d5_size, d5_ld
         integer :: lbound5_, range5_(2)
         integer :: d6_start, d6_end, d6_size, d6_ld
         integer :: lbound6_, range6_(2)
         !
         lbound1_=1
         if (present(lbound1)) lbound1_=lbound1 
         range1_=(/1,size(array_out, 1)/)
         if (present(range1)) range1_=range1 
         !
         d1_start = range1_(1) -lbound1_ +1
         d1_end   = range1_(2) -lbound1_ +1
         d1_size  = range1_(2) -range1_(1) + 1
         d1_ld    = size(array_out, 1)
         lbound2_=1
         if (present(lbound2)) lbound2_=lbound2 
         range2_=(/1,size(array_out, 2)/)
         if (present(range2)) range2_=range2 
         !
         d2_start = range2_(1) -lbound2_ +1
         d2_end   = range2_(2) -lbound2_ +1
         d2_size  = range2_(2) -range2_(1) + 1
         d2_ld    = size(array_out, 2)
         lbound3_=1
         if (present(lbound3)) lbound3_=lbound3 
         range3_=(/1,size(array_out, 3)/)
         if (present(range3)) range3_=range3 
         !
         d3_start = range3_(1) -lbound3_ +1
         d3_end   = range3_(2) -lbound3_ +1
         d3_size  = range3_(2) -range3_(1) + 1
         d3_ld    = size(array_out, 3)
         lbound4_=1
         if (present(lbound4)) lbound4_=lbound4 
         range4_=(/1,size(array_out, 4)/)
         if (present(range4)) range4_=range4 
         !
         d4_start = range4_(1) -lbound4_ +1
         d4_end   = range4_(2) -lbound4_ +1
         d4_size  = range4_(2) -range4_(1) + 1
         d4_ld    = size(array_out, 4)
         lbound5_=1
         if (present(lbound5)) lbound5_=lbound5 
         range5_=(/1,size(array_out, 5)/)
         if (present(range5)) range5_=range5 
         !
         d5_start = range5_(1) -lbound5_ +1
         d5_end   = range5_(2) -lbound5_ +1
         d5_size  = range5_(2) -range5_(1) + 1
         d5_ld    = size(array_out, 5)
         lbound6_=1
         if (present(lbound6)) lbound6_=lbound6 
         range6_=(/1,size(array_out, 6)/)
         if (present(range6)) range6_=range6 
         !
         d6_start = range6_(1) -lbound6_ +1
         d6_end   = range6_(2) -lbound6_ +1
         d6_size  = range6_(2) -range6_(1) + 1
         d6_ld    = size(array_out, 6)
#if defined __DXL_CUDAF
         ierr = CudaMemcpyAsync(array_out, array_in, &
                                count=d1_size*d2_size*d3_size*d4_size*d5_size*d6_size,&
                                kdir=cudaMemcpyHostToDevice,stream=async_id)
         if ( ierr /= 0) call devxlib_error("l4_memcpy_d2h_async_l6d",cudaGetErrorString(ierr),ierr)
#elif defined __DXL_OPENACC || defined __DXL_OPENMP_GPU
         !DEV_ACC update host(array_in) async(async_id)
         !DEV_OMPGPU target update from(array_in)
         !
         ptr1=c_loc(array_out(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         ptr2=c_loc( array_in(d1_start,d2_start,d3_start,d4_start,d5_start,d6_start))
         !
         if ( .not. c_associated(ptr1,ptr2)) then
           !DEV_ACC wait(async_id)
           array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                   array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
         endif
#else
         array_out(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end) = &
                 array_in(d1_start:d1_end,d2_start:d2_end,d3_start:d3_end,d4_start:d4_end,d5_start:d5_end,d6_start:d6_end)
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_async_l6d
!
      module subroutine sp_devxlib_memcpy_d2h_r1d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real32), pointer, intent(inout) DEV_ATTR :: array_in(:)
         real(real32),  target, intent(inout) :: array_out(:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r1d_p
!
      module subroutine sp_devxlib_memcpy_d2h_r2d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:)
         real(real32),  target, intent(inout) :: array_out(:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r2d_p
!
      module subroutine sp_devxlib_memcpy_d2h_r3d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:)
         real(real32),  target, intent(inout) :: array_out(:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r3d_p
!
      module subroutine sp_devxlib_memcpy_d2h_r4d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         real(real32),  target, intent(inout) :: array_out(:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r4d_p
!
      module subroutine sp_devxlib_memcpy_d2h_r5d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         real(real32),  target, intent(inout) :: array_out(:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r5d_p
!
      module subroutine sp_devxlib_memcpy_d2h_r6d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         real(real32),  target, intent(inout) :: array_out(:,:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_r6d_p
!
      module subroutine dp_devxlib_memcpy_d2h_r1d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real64), pointer, intent(inout) DEV_ATTR :: array_in(:)
         real(real64),  target, intent(inout) :: array_out(:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r1d_p
!
      module subroutine dp_devxlib_memcpy_d2h_r2d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:)
         real(real64),  target, intent(inout) :: array_out(:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r2d_p
!
      module subroutine dp_devxlib_memcpy_d2h_r3d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:)
         real(real64),  target, intent(inout) :: array_out(:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r3d_p
!
      module subroutine dp_devxlib_memcpy_d2h_r4d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         real(real64),  target, intent(inout) :: array_out(:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r4d_p
!
      module subroutine dp_devxlib_memcpy_d2h_r5d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         real(real64),  target, intent(inout) :: array_out(:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r5d_p
!
      module subroutine dp_devxlib_memcpy_d2h_r6d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         real(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         real(real64),  target, intent(inout) :: array_out(:,:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_r6d_p
!
      module subroutine sp_devxlib_memcpy_d2h_c1d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real32), pointer, intent(inout) DEV_ATTR :: array_in(:)
         complex(real32),  target, intent(inout) :: array_out(:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c1d_p
!
      module subroutine sp_devxlib_memcpy_d2h_c2d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:)
         complex(real32),  target, intent(inout) :: array_out(:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c2d_p
!
      module subroutine sp_devxlib_memcpy_d2h_c3d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:)
         complex(real32),  target, intent(inout) :: array_out(:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c3d_p
!
      module subroutine sp_devxlib_memcpy_d2h_c4d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         complex(real32),  target, intent(inout) :: array_out(:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c4d_p
!
      module subroutine sp_devxlib_memcpy_d2h_c5d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         complex(real32),  target, intent(inout) :: array_out(:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c5d_p
!
      module subroutine sp_devxlib_memcpy_d2h_c6d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         complex(real32),  target, intent(inout) :: array_out(:,:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine sp_devxlib_memcpy_d2h_c6d_p
!
      module subroutine dp_devxlib_memcpy_d2h_c1d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real64), pointer, intent(inout) DEV_ATTR :: array_in(:)
         complex(real64),  target, intent(inout) :: array_out(:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c1d_p
!
      module subroutine dp_devxlib_memcpy_d2h_c2d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:)
         complex(real64),  target, intent(inout) :: array_out(:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c2d_p
!
      module subroutine dp_devxlib_memcpy_d2h_c3d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:)
         complex(real64),  target, intent(inout) :: array_out(:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c3d_p
!
      module subroutine dp_devxlib_memcpy_d2h_c4d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         complex(real64),  target, intent(inout) :: array_out(:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c4d_p
!
      module subroutine dp_devxlib_memcpy_d2h_c5d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         complex(real64),  target, intent(inout) :: array_out(:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c5d_p
!
      module subroutine dp_devxlib_memcpy_d2h_c6d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         complex(real64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         complex(real64),  target, intent(inout) :: array_out(:,:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine dp_devxlib_memcpy_d2h_c6d_p
!
      module subroutine i4_devxlib_memcpy_d2h_i1d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int32), pointer, intent(inout) DEV_ATTR :: array_in(:)
         integer(int32),  target, intent(inout) :: array_out(:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i1d_p
!
      module subroutine i4_devxlib_memcpy_d2h_i2d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:)
         integer(int32),  target, intent(inout) :: array_out(:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i2d_p
!
      module subroutine i4_devxlib_memcpy_d2h_i3d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:)
         integer(int32),  target, intent(inout) :: array_out(:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i3d_p
!
      module subroutine i4_devxlib_memcpy_d2h_i4d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         integer(int32),  target, intent(inout) :: array_out(:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i4d_p
!
      module subroutine i4_devxlib_memcpy_d2h_i5d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         integer(int32),  target, intent(inout) :: array_out(:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i5d_p
!
      module subroutine i4_devxlib_memcpy_d2h_i6d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         integer(int32),  target, intent(inout) :: array_out(:,:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i4_devxlib_memcpy_d2h_i6d_p
!
      module subroutine i8_devxlib_memcpy_d2h_i1d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int64), pointer, intent(inout) DEV_ATTR :: array_in(:)
         integer(int64),  target, intent(inout) :: array_out(:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i1d_p
!
      module subroutine i8_devxlib_memcpy_d2h_i2d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int64), pointer, intent(inout) DEV_ATTR :: array_in(:,:)
         integer(int64),  target, intent(inout) :: array_out(:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i2d_p
!
      module subroutine i8_devxlib_memcpy_d2h_i3d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:)
         integer(int64),  target, intent(inout) :: array_out(:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i3d_p
!
      module subroutine i8_devxlib_memcpy_d2h_i4d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         integer(int64),  target, intent(inout) :: array_out(:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i4d_p
!
      module subroutine i8_devxlib_memcpy_d2h_i5d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         integer(int64),  target, intent(inout) :: array_out(:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i5d_p
!
      module subroutine i8_devxlib_memcpy_d2h_i6d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         integer(int64), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         integer(int64),  target, intent(inout) :: array_out(:,:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine i8_devxlib_memcpy_d2h_i6d_p
!
      module subroutine l4_devxlib_memcpy_d2h_l1d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         logical(int32), pointer, intent(inout) DEV_ATTR :: array_in(:)
         logical(int32),  target, intent(inout) :: array_out(:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l1d_p
!
      module subroutine l4_devxlib_memcpy_d2h_l2d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         logical(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:)
         logical(int32),  target, intent(inout) :: array_out(:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l2d_p
!
      module subroutine l4_devxlib_memcpy_d2h_l3d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         logical(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:)
         logical(int32),  target, intent(inout) :: array_out(:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l3d_p
!
      module subroutine l4_devxlib_memcpy_d2h_l4d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         logical(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:)
         logical(int32),  target, intent(inout) :: array_out(:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l4d_p
!
      module subroutine l4_devxlib_memcpy_d2h_l5d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         logical(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:)
         logical(int32),  target, intent(inout) :: array_out(:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l5d_p
!
      module subroutine l4_devxlib_memcpy_d2h_l6d_p(&
#if defined __DXL_OPENMP_GPU
                                             array_out, array_in, device_id)
#else
                                             array_out, array_in)
#endif
         implicit none
         !
         logical(int32), pointer, intent(inout) DEV_ATTR :: array_in(:,:,:,:,:,:)
         logical(int32),  target, intent(inout) :: array_out(:,:,:,:,:,:)
#if defined __DXL_OPENMP_GPU
         integer,         optional, intent(in)    :: device_id
#endif
         !
#if defined __DXL_CUDAF || defined __DXL_OPENMP_GPU
         integer :: ierr = 0
#endif
         !
#if defined __DXL_CUDAF
         ierr = cudaMemcpy_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                             size(array_in,kind=int64) / 8_int64,c_size_t), cudaMemcpyDeviceToHost)
#elif defined __DXL_OPENACC
         call acc_memcpy_from_device_f(c_loc(array_out), c_loc(array_in), int(storage_size(array_in,kind=int64) * &
                                       size(array_in,kind=int64) / 8_int64, c_size_t))
#elif defined __DXL_OPENMP_GPU
         if (present(device_id)) then
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), device_id), kind=int32)
         else
            ierr = int(omp_target_memcpy(c_loc(array_out), c_loc(array_in), int(storage_size(array_out,kind=int64) * &
                       size(array_out,kind=int64) / 8_int64, c_size_t), int(0,c_size_t), int(0,c_size_t), omp_get_initial_device(), omp_get_default_device()), kind=int32)
         endif
#else
         ! host2host fall-back
         array_out=array_in
#endif
         !
      end subroutine l4_devxlib_memcpy_d2h_l6d_p
!
endsubmodule devxlib_memcpy_d2h
