!
! 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 device_auxfunc_vec_upd.jf90
!==================================================================
!==================================================================
!
#include<devxlib_macros.h>
#include<devxlib_defs.h>
!
!=======================================
!
submodule (devxlib_auxfunc) devxlib_auxfunc_vec_upd

   implicit none

   contains
{% set d=1 %}
{%- for p in precision %}
{%- for t in types %}
      module subroutine {{p.name}}_devxlib_vec_upd_remap_{{t[0]|lower}}{{d}}d(ndim, vout, v1, map1, scal)
         implicit none
         !   
         integer,      intent(in)    :: ndim
         {{t}}({{p.val}}) DEV_ATTR, intent(inout) :: vout({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         {{t}}({{p.val}}) DEV_ATTR, intent(in)    :: v1({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         integer DEV_ATTR,      intent(in)    :: map1({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         {{t}}({{p.val}}), optional, intent(in)   :: scal
         integer :: i
         !   
         if (present(scal)) then
            !DEV_CUF kernel do(1)
            !DEV_ACC data present(vout,v1,map1)
            !DEV_ACC parallel loop async
            !DEV_OMPGPU target map(present,alloc:vout,v1,map1) nowait
            !DEV_OMPGPU teams loop
            do i = 1, ndim
               vout(i) = v1(map1(i))*scal
            enddo
            !DEV_ACC end data
            !DEV_OMPGPU end target
         else
            !DEV_CUF kernel do(1)
            !DEV_ACC data present(vout,v1,map1)
            !DEV_ACC parallel loop async
            !DEV_OMPGPU target map(present,alloc:vout,v1,map1) nowait
            !DEV_OMPGPU teams loop
            do i = 1, ndim
               vout(i) = v1(map1(i))
            enddo
            !DEV_ACC end data
            !DEV_OMPGPU end target
         endif
      end subroutine {{p.name}}_devxlib_vec_upd_remap_{{t[0]|lower}}{{d}}d
      !
{%- endfor %}
{%- endfor %}

{% set d=1 %}
{%- for p in precision %}
{%- for t in types %}
      module subroutine {{p.name}}_devxlib_vec_upd_v_remap_v_{{t[0]|lower}}{{d}}d(ndim, vout, v1, map1, v2, scal)
         implicit none
         !   
         integer,      intent(in)    :: ndim
         {{t}}({{p.val}}), intent(inout) DEV_ATTR :: vout({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         {{t}}({{p.val}}), intent(in)    DEV_ATTR :: v1({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         integer,      intent(in)    DEV_ATTR :: map1({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         {{t}}({{p.val}}), intent(in)    DEV_ATTR :: v2({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         {{t}}({{p.val}}), optional, intent(in)   :: scal
         integer :: i
         !   
         if (present(scal)) then
            !DEV_CUF kernel do(1)
            do i = 1, ndim
               vout(i) = v1(map1(i))*v2(i)*scal
            enddo
         else
            !DEV_CUF kernel do(1)
            do i = 1, ndim
               vout(i) = v1(map1(i))*v2(i)
            enddo
         endif
      end subroutine {{p.name}}_devxlib_vec_upd_v_remap_v_{{t[0]|lower}}{{d}}d
      !
{%- endfor %}
{%- endfor %}
!
!======================
!
{% set d=1 %}
{% set t= "complex" %}
{%- for p in precision %}
      module subroutine {{p.name}}_devxlib_vec_upd_v_remap_v_x_{{t[0]|lower}}{{d}}d(ndim, vout, v1,op1, map1, v2,op2, scal)
         implicit none
         !   
         integer,      intent(in)    :: ndim
         {{t}}({{p.val}}), intent(inout) DEV_ATTR :: vout({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         {{t}}({{p.val}}), intent(in)    DEV_ATTR :: v1({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         integer,      intent(in)    DEV_ATTR :: map1({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         {{t}}({{p.val}}), intent(in)    DEV_ATTR :: v2({% for dd in range(d) %}:{% if not loop.last %}, {%- endif %}{% endfor %}) 
         character(1), intent(in)    :: op1, op2
         {{t}}({{p.val}}), optional, intent(in)    :: scal
         integer :: i
         !
         if (op1=="N".and.op2=="N") then
            if (present(scal)) then
               !DEV_CUF kernel do(1)
               do i = 1, ndim
                  vout(i) = v1(map1(i))*v2(i)*scal
               enddo
            else
               !DEV_CUF kernel do(1)
               do i = 1, ndim
                  vout(i) = v1(map1(i))*v2(i)
               enddo
            endif
         elseif (op1=="C".and.op2=="N") then
            if (present(scal)) then
               !DEV_CUF kernel do(1)
               do i = 1, ndim
                  vout(i) = conjg(v1(map1(i)))*v2(i)*scal
               enddo
            else
               !DEV_CUF kernel do(1)
               do i = 1, ndim
                  vout(i) = conjg(v1(map1(i)))*v2(i)
               enddo
            endif
         elseif (op1=="N".and.op2=="C") then
            if (present(scal)) then
               !DEV_CUF kernel do(1)
               do i = 1, ndim
                  vout(i) = v1(map1(i))*conjg(v2(i))*scal
               enddo
            else
               !DEV_CUF kernel do(1)
               do i = 1, ndim
                  vout(i) = v1(map1(i))*conjg(v2(i))
               enddo
            endif
         elseif (op1=="N".and.op2=="C") then
            if (present(scal)) then
               !DEV_CUF kernel do(1)
               do i = 1, ndim
                  vout(i) = conjg(v1(map1(i)))*conjg(v2(i))*scal
               enddo
            else
               !DEV_CUF kernel do(1)
               do i = 1, ndim
                  vout(i) = conjg(v1(map1(i)))*conjg(v2(i))
               enddo
            endif
         else
            call devxlib_error("{{p.name}}_devxlib_vec_upd_v_remap_v_x_{{t[0]|lower}}{{d}}d","invalid op1/op2",10)
         endif
         !
      end subroutine {{p.name}}_devxlib_vec_upd_v_remap_v_x_{{t[0]|lower}}{{d}}d
      !
{%- endfor %}

end submodule devxlib_auxfunc_vec_upd
