!===============================================================================
!
! cg_copy_spincol_simd.F90
!
!-------------------------------------------------------------------------------
!
! Copyright (C) 2012-2016 Hinnerk Stueben
!
! This file is part of BQCD -- Berlin Quantum ChromoDynamics program
!
! BQCD is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! BQCD is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with BQCD.  If not, see <http://www.gnu.org/licenses/>.
!
!-------------------------------------------------------------------------------
# define LANGUAGE_FORTRAN
# define SIMD
# include "defs.h"
# include "cg_defs.h"
# include "simd.h"

!-------------------------------------------------------------------------------
# undef TRACE_NAME
# define TRACE_NAME T(cg_copyin)
!-------------------------------------------------------------------------------
subroutine T(cg_copyin)(out, in)

  use module_simd
  use T(module_vol)
  implicit none
  complex(8), intent(in)     :: in(NDIRAC2, NDIRAC2, NCOL, *)
  spincol_FIELD, intent(out) :: out
  integer :: i, j, w

  TRACE_ENTRY

  !$omp parallel do private(i, w)
  do j = 0, volh - 1
     i = j * SIMD_WIDTH
     do w = 1, SIMD_WIDTH
     DO c = 1, 3
     DO s2 = 1, 2
     DO s1 = 1, 2
        Spincol(out, s1, s2, c, j+1)%r(w) = real(in(s1, s2, c, i+w))
        Spincol(out, s1, s2, c, j+1)%i(w) = aimag(in(s1, s2, c, i+w))
     ENDDO
     ENDDO
     ENDDO
     enddo
  enddo

  TRACE_RETURN
end

!-------------------------------------------------------------------------------
# undef TRACE_NAME
# define TRACE_NAME T(cg_copyout)
!-------------------------------------------------------------------------------
subroutine T(cg_copyout)(out, in)

  use module_simd
  use T(module_vol)
  implicit none
  spincol_FIELD, intent(in) :: in
  complex(8), intent(out)   :: out(NDIRAC2, NDIRAC2, NCOL, *)
  integer :: i, j, w

  TRACE_ENTRY

  !$omp parallel do private(i, w)
  do j = 0, volh - 1
     i = j * SIMD_WIDTH
     do w = 1, SIMD_WIDTH
     DO c = 1, 3
     DO s2 = 1, 2
     DO s1 = 1, 2
        out(s1, s2, c, i+w) = cmplx(Spincol(in, s1, s2, c, j+1)%r(w), &
                                    Spincol(in, s1, s2, c, j+1)%i(w), &
                                    kind=RKIND) 
     ENDDO
     ENDDO
     ENDDO
     enddo
  enddo

  TRACE_RETURN
end

!-------------------------------------------------------------------------------
# undef TRACE_NAME
# define TRACE_NAME T(cg_copy_caxpy)
!-------------------------------------------------------------------------------
subroutine T(cg_copy_caxpy)(inout, in, a)  ! inout = inout + a * in

  use module_simd
  use T(module_vol)
  implicit none
  complex(8), intent(inout) :: inout(NDIRAC2, NDIRAC2, NCOL, *)
  spincol_FIELD, intent(in) :: in
  COMPLEX, intent(in)       :: a 
  integer :: i, j, w

  TRACE_ENTRY

  !$omp parallel do private(i, w)
  do j = 0, volh - 1
     i = j * SIMD_WIDTH
     do w = 1, SIMD_WIDTH
     DO c = 1, 3
     DO s2 = 1, 2
     DO s1 = 1, 2
        inout(s1, s2, c, i+w) = inout(s1, s2, c, i+w) + a * &
                              cmplx(Spincol(in, s1, s2, c, j+1)%r(w), &
                                    Spincol(in, s1, s2, c, j+1)%i(w), &
                                    kind=RKIND) 
     ENDDO
     ENDDO
     ENDDO
     enddo
  enddo

  TRACE_RETURN
end

!===============================================================================
