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

   implicit none

   contains
!
{%- macro decorate(label) -%}
   {%- if label == "begin" -%}
       !DEV_CUF kernel do(2)
       !DEV_OMP parallel do default(shared), private(i,j), collapse(2)
   {%- endif%}
   {%- if label == "end" -%}
   {%- endif%}
{%- endmacro -%}

{% set d=2 %}
{%- for p in precision %}
{%- for t in types %}
      module subroutine {{p.name}}_devxlib_mat_upd_dMd_{{t[0]|lower}}{{d}}d(ndim1, ndim2, mat, v1,op1, v2,op2, scal)
         !
         ! performs: mat(i,j) = scal * op1(v1(i)) * mat(i,j) * op2(v2(j))
         ! op = 'N', 'R', 'C',       'RC'
         !       x   1/x  conjg(x)   conjg(1/x)
         implicit none
         !   
         integer,      intent(in)    :: ndim1,ndim2
         {{t}}({{p.val}}), intent(inout) DEV_ATTR :: mat(:,:)
         {{t}}({{p.val}}), intent(in)    DEV_ATTR :: v1(:)
         {{t}}({{p.val}}), intent(in)    DEV_ATTR :: v2(:)
         character(1), intent(in)    :: op1, op2
         {{t}}({{p.val}}), optional, intent(in)  :: scal
         integer :: i,j
         !   
         if (op1=="N".and.op2=="N") then
            if (present(scal)) then
{{decorate('begin')}}
               do j = 1, ndim2
                  do i = 1, ndim1
                     mat(i,j) = scal * v1(i) * mat(i,j) * v2(j)
                  enddo
               enddo
{{decorate('end')}}
            else
{{decorate('begin')}}
               do j = 1, ndim2
                  do i = 1, ndim1
                     mat(i,j) = v1(i) * mat(i,j) * v2(j)
                  enddo
               enddo
{{decorate('end')}}
            endif
         elseif (op1=="R".and.op2=="R") then
            if (present(scal)) then
{{decorate('begin')}}
               do j = 1, ndim2
                  do i = 1, ndim1
                     mat(i,j) = scal / v1(i) * mat(i,j) / v2(j)
                  enddo
               enddo
{{decorate('end')}}
            else
{{decorate('begin')}}
               do j = 1, ndim2
                  do i = 1, ndim1
                     mat(i,j) = mat(i,j) /v1(i) / v2(j)
                  enddo
               enddo
{{decorate('end')}}
            endif
{%- if t == "complex" %}
         elseif (op1=="C".and.op2=="C") then
            if (present(scal)) then
{{decorate('begin')}}
               do j = 1, ndim2
                  do i = 1, ndim1
                     mat(i,j) = scal * conjg(v1(i)) * mat(i,j) * conjg(v2(j))
                  enddo
               enddo
{{decorate('end')}}
            else
{{decorate('begin')}}
               do j = 1, ndim2
                  do i = 1, ndim1
                     mat(i,j) = conjg(v1(i)) * mat(i,j) * conjg(v2(j))
                  enddo
               enddo
{{decorate('end')}}
            endif
{%- endif %}
         else
            call devxlib_error("{{p.name}}_mat_upd_dMd_{{t[0]|lower}}{{d}}d","invalid op1/op2",10)
         endif
         !
      end subroutine {{p.name}}_devxlib_mat_upd_dMd_{{t[0]|lower}}{{d}}d
      !
{%- endfor %}
{%- endfor %}

end submodule devxlib_auxfunc_mat_upd
