!
! Copyright (C) 2021, MaX CoE
! Distributed under the MIT License 
! (license terms are at http://opensource.org/licenses/MIT).
!
!--
!
! Auxiliary functions
!
! AF: OpenACC support is incomplete !!
!
!==================================================================
!==================================================================
! *DO NOT EDIT*: automatically generated from devxlib_auxfunc_conj.jf90
!==================================================================
!==================================================================
!
#include<devxlib_macros.h>
#include<devxlib_defs.h>
!
!=======================================
!
submodule (devxlib_auxfunc) devxlib_auxfunc_conjg

   implicit none

   contains
{% set t='complex' %}
{%- for p in precision %}
{%- for d in range(1,dimensions+1) %}
      module subroutine {{p.name}}_devxlib_conjg_{{t[0]|lower}}{{d}}d(array_inout, async_id, &
                                        {% for dd in range(d) %} 
                                        {{ "range%s"|format(dd+1) }}, {{ "lbound%s"|format(dd+1) }}{% if not loop.last %}, &
                                        {%- endif %}{% endfor %} )
         implicit none
         !
         {{t}}({{p.val}}) DEV_ATTR, intent(inout) :: array_inout({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %})
         integer(kind=dxl_async_kind), optional, intent(in) :: async_id
         integer, optional, intent(in) :: {% for dd in range(d) %} {{ "range%s(2)"|format(dd+1) }}{% if not loop.last %}, {%- endif %}{% endfor %}
         integer, optional, intent(in) :: {% for dd in range(d) %} {{ "lbound%s"  |format(dd+1) }}{% if not loop.last %}, {%- endif %}{% endfor %}
         !
{%- for dd in range(d) %}
         integer :: i{{dd+1}}, d{{dd+1}}s, d{{dd+1}}e
         integer :: lbound{{dd+1}}_, range{{dd+1}}_(2)
{%- endfor %}
         !
{%- for dd in range(d) %}
         lbound{{dd+1}}_=1
         if (present(lbound{{dd+1}})) lbound{{dd+1}}_=lbound{{dd+1}} 
         range{{dd+1}}_=(/1,size(array_inout, {{dd+1}})/)
         if (present(range{{dd+1}})) range{{dd+1}}_=range{{dd+1}} 
         !
         d{{dd+1}}s = range{{dd+1}}_(1) -lbound{{dd+1}}_ +1
         d{{dd+1}}e = range{{dd+1}}_(2) -lbound{{dd+1}}_ +1
         !
{%- endfor %}
         !
         if (present(async_id)) then
            !
            !DEV_CUF kernel do({{d}}) <<<*,*,0,stream=async_id>>>
            !DEV_ACC data present(array_inout)
            !DEV_ACC parallel loop collapse({{d}}) async(async_id)
            !DEV_OMPGPU target map(present,alloc:array_inout)
            !DEV_OMPGPU teams loop collapse({{d}})
            !DEV_OMP  parallel do
{%- for dd in range(d,0,-1) %}
            do i{{dd}} = d{{dd}}s, d{{dd}}e
{%- endfor %}
               array_inout( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) = &
                   conjg (  array_inout ( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) )
{%- for dd in range(d) %}
            enddo
{%- endfor %}
            !DEV_ACC end data
            !DEV_OMPGPU end target
            !
         else
            !
            !DEV_CUF kernel do({{d}})
            !DEV_ACC data present(array_inout)
            !DEV_ACC parallel loop collapse({{d}})
            !DEV_OMPGPU target map(present,alloc:array_inout)
            !DEV_OMPGPU teams loop collapse({{d}})
            !DEV_OMP  parallel do
{%- for dd in range(d,0,-1) %}
            do i{{dd}} = d{{dd}}s, d{{dd}}e
{%- endfor %}
               array_inout( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) = &
                   conjg (  array_inout ( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) )
{%- for dd in range(d) %}
            enddo
{%- endfor %}
            !DEV_ACC end data
            !DEV_OMPGPU end target
            !
         endif
          !
      end subroutine {{p.name}}_devxlib_conjg_{{t[0]|lower}}{{d}}d
      !
{%- endfor %}
{%- endfor %}

{% set t='complex' %}
{%- for p in precision %}
{%- for d in range(1,dimensions+1) %}
      module subroutine {{p.name}}_devxlib_conjg_{{t[0]|lower}}{{d}}d_p(ptr_inout, async_id, &
                                        {% for dd in range(d) %} 
                                        {{ "range%s"|format(dd+1) }}, {{ "lbound%s"|format(dd+1) }}{% if not loop.last %}, &
                                        {%- endif %}{% endfor %} )
         implicit none
         !
         {{t}}({{p.val}}), pointer, contiguous, intent(inout) DEV_ATTR :: ptr_inout({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %})
         integer(kind=dxl_async_kind), optional, intent(in) :: async_id
         integer, optional, intent(in) :: {% for dd in range(d) %} {{ "range%s(2)"|format(dd+1) }}{% if not loop.last %}, {%- endif %}{% endfor %}
         integer, optional, intent(in) :: {% for dd in range(d) %} {{ "lbound%s"  |format(dd+1) }}{% if not loop.last %}, {%- endif %}{% endfor %}
         !
{%- for dd in range(d) %}
         integer :: i{{dd+1}}, d{{dd+1}}s, d{{dd+1}}e
         integer :: lbound{{dd+1}}_, range{{dd+1}}_(2)
{%- endfor %}
         !
{%- for dd in range(d) %}
         lbound{{dd+1}}_=1
         if (present(lbound{{dd+1}})) lbound{{dd+1}}_=lbound{{dd+1}} 
         range{{dd+1}}_=(/1,size(ptr_inout, {{dd+1}})/)
         if (present(range{{dd+1}})) range{{dd+1}}_=range{{dd+1}} 
         !
         d{{dd+1}}s = range{{dd+1}}_(1) -lbound{{dd+1}}_ +1
         d{{dd+1}}e = range{{dd+1}}_(2) -lbound{{dd+1}}_ +1
         !
{%- endfor %}
         !
         if (present(async_id)) then
            !
            !DEV_CUF kernel do({{d}}) <<<*,*,0,stream=async_id>>>
#if defined __GFORTRAN__
            !DEV_ACC data present(ptr_inout)
#else
            !DEV_ACC data deviceptr(ptr_inout)
#endif
            !DEV_ACC parallel loop collapse({{d}}) async(async_id)
            !DEV_OMPGPU target 
            !DEV_OMPGPU teams loop collapse({{d}})
            !DEV_OMP  parallel do
{%- for dd in range(d,0,-1) %}
            do i{{dd}} = d{{dd}}s, d{{dd}}e
{%- endfor %}
               ptr_inout( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) = &
                   conjg (  ptr_inout ( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) )
{%- for dd in range(d) %}
            enddo
{%- endfor %}
            !DEV_ACC end data
            !DEV_OMPGPU end target
            !
         else
            !
            !DEV_CUF kernel do({{d}})
#if defined __GFORTRAN__
            !DEV_ACC data present(ptr_inout)
#else
            !DEV_ACC data deviceptr(ptr_inout)
#endif
            !DEV_ACC parallel loop collapse({{d}})
            !DEV_OMPGPU target 
            !DEV_OMPGPU teams loop collapse({{d}})
            !DEV_OMP  parallel do
{%- for dd in range(d,0,-1) %}
            do i{{dd}} = d{{dd}}s, d{{dd}}e
{%- endfor %}
               ptr_inout( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) = &
                   conjg (  ptr_inout ( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) )
{%- for dd in range(d) %}
            enddo
{%- endfor %}
            !DEV_ACC end data
            !DEV_OMPGPU end target
            !
         endif
          !
      end subroutine {{p.name}}_devxlib_conjg_{{t[0]|lower}}{{d}}d_p
      !
{%- endfor %}
{%- endfor %}

{% set t='complex' %}
{%- for p in precision %}
{%- for d in range(1,dimensions+1) %}
      module subroutine {{p.name}}_devxlib_conjg_h_{{t[0]|lower}}{{d}}d(array_inout, async_id, &
                                        {% for dd in range(d) %} 
                                        {{ "range%s"|format(dd+1) }}, {{ "lbound%s"|format(dd+1) }}{% if not loop.last %}, &
                                        {%- endif %}{% endfor %} )
         implicit none
         !
         {{t}}({{p.val}}), intent(inout) :: array_inout({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %})
         integer(kind=dxl_async_kind), optional, intent(in) :: async_id
         integer, optional, intent(in) :: {% for dd in range(d) %} {{ "range%s(2)"|format(dd+1) }}{% if not loop.last %}, {%- endif %}{% endfor %}
         integer, optional, intent(in) :: {% for dd in range(d) %} {{ "lbound%s"  |format(dd+1) }}{% if not loop.last %}, {%- endif %}{% endfor %}
         !
{%- for dd in range(d) %}
         integer :: i{{dd+1}}, d{{dd+1}}s, d{{dd+1}}e
         integer :: lbound{{dd+1}}_, range{{dd+1}}_(2)
{%- endfor %}
         !
{%- for dd in range(d) %}
         lbound{{dd+1}}_=1
         if (present(lbound{{dd+1}})) lbound{{dd+1}}_=lbound{{dd+1}} 
         range{{dd+1}}_=(/1,size(array_inout, {{dd+1}})/)
         if (present(range{{dd+1}})) range{{dd+1}}_=range{{dd+1}} 
         !
         d{{dd+1}}s = range{{dd+1}}_(1) -lbound{{dd+1}}_ +1
         d{{dd+1}}e = range{{dd+1}}_(2) -lbound{{dd+1}}_ +1
         !
{%- endfor %}
         !
{%- for dd in range(d,0,-1) %}
         do i{{dd}} = d{{dd}}s, d{{dd}}e
{%- endfor %}
            array_inout( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) = &
                conjg (  array_inout ( {%- for dd in range(d) %}i{{dd+1}}{% if not loop.last %}, {%- endif %} {%- endfor %} ) )
{%- for dd in range(d) %}
         enddo
{%- endfor %}
         !
      end subroutine {{p.name}}_devxlib_conjg_h_{{t[0]|lower}}{{d}}d
      !
{%- endfor %}
{%- endfor %}

end submodule devxlib_auxfunc_conjg
