!===============================================================================
!
! module_cg_procs.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

!-------------------------------------------------------------------------------
module module_cg_procs

  type type_cg_procs
     procedure(), nopass, pointer :: d
     procedure(), nopass, pointer :: d_dag
     procedure(), nopass, pointer :: co     ! old name: clover_mult_ao()
     procedure(), nopass, pointer :: c2     ! old name: clover_mult_a2()
     procedure(), nopass, pointer :: loop1
     procedure(), nopass, pointer :: loop2
     procedure(), nopass, pointer :: loop3
     procedure(), nopass, pointer :: axpy
     procedure(), nopass, pointer :: xpby
     procedure(), nopass, pointer :: norm2
     procedure(), nopass, pointer :: cdotc

     procedure(), nopass, pointer :: copyin_gauge
     procedure(), nopass, pointer :: copyin_clover
     procedure(), nopass, pointer :: copyin_spincol
     procedure(), nopass, pointer :: copyout_spincol
     procedure(), nopass, pointer :: copy_caxpy

     procedure(), nopass, pointer :: kernel
     procedure(), nopass, pointer :: kernel_cg
     procedure(), nopass, pointer :: kernel_mcg
     procedure(), nopass, pointer :: kernel_mbcg
     procedure(), nopass, pointer :: mm
     procedure(), nopass, pointer :: ww
  end type type_cg_procs

  type(type_cg_procs), save :: cg_procs

  interface
     subroutine cg_set_proc(p, s)
       procedure(), pointer :: p
       character(*) :: s
     end subroutine cg_set_proc
  end interface

FOR proc in loop1 loop2 loop3 axpy xpby norm2 cdotc
FOR sc in _sc _sc22
FOR block in '' _block
FOR _rr in _r4 _r8
FOR simd in '' s
  procedure() :: cg_ %% proc %% block %% sc %% _rr %% simd
ENDFOR
ENDFOR
ENDFOR
ENDFOR
ENDFOR

FOR proc in co c2
FOR clover in _c1 _c2
FOR sc in _sc _sc22
FOR block in '' _block
FOR _rr in _r4 _r8
FOR simd in '' s
  procedure() :: cg_ %% proc %% block %% clover %% sc %% _rr %% simd
ENDFOR
ENDFOR
ENDFOR
ENDFOR
ENDFOR
ENDFOR

!!!FOR proc in copyin copyout kernel2 mm d2 d2_dag d21 d21_dag d102 d102_dag
!!!FOR proc in copyin copyout kernel2 mm d21 d21_dag

FOR proc in copyin copyout copy_caxpy kernel2 kernel_cg kernel_mcg kernel_mbcg mm ww d2 d2_dag d21 d21_dag d25 d25_dag d35 d35_dag
FOR field in _sc _sc22
FOR _rr in _r4 _r8
FOR simd in '' s
  procedure() :: cg_ %% proc %% field %% _rr %% simd
ENDFOR
ENDFOR
ENDFOR
ENDFOR

FOR field in _g1 _g2 _c1 _c2
FOR _rr in _r4 _r8
FOR simd in '' s
  procedure() :: cg_copyin %% field %% _rr %% simd
ENDFOR
ENDFOR
ENDFOR

end
!===============================================================================
