/********************  s_m_a_wvec.c  (in su3.a) ********************
*
*void scalar_mult_add_wvec(wilson_vector *src1, wilson_vector *src2,
	double s, wilson_vector *dest)
*  Multiply a Wilson vector by a scalar and add to another vector
* dest  <-  src1 + s*src2
*/
#include "../include/config.h"
#include "../include/complex.h"
#include "../include/su3.h"

extern __targetConst__ int t_sites_on_node;

__targetEntry__  void scalar_mult_add_wvec_lattice( wilson_vector * src1, wilson_vector * src2, const double sval, wilson_vector * dest ){

    int i;
    __targetTLP__(i,t_sites_on_node){
      scalar_mult_add_wvec_tdp((double*) &(src1[0]),(double*) &(src2[0]),sval,(double*) &(dest[0]),i);
    }

  return;

}

__targetHost__ __target__ void scalar_mult_add_wvec( wilson_vector * src1, wilson_vector * src2, double s, wilson_vector * dest )
{

    register double ss;
    ss = s;

    dest->COLORSPINOR( 0, 0 ).real = src1->COLORSPINOR( 0, 0 ).real + ss * src2->COLORSPINOR( 0, 0 ).real;
    dest->COLORSPINOR( 0, 0 ).imag = src1->COLORSPINOR( 0, 0 ).imag + ss * src2->COLORSPINOR( 0, 0 ).imag;
    dest->COLORSPINOR( 1, 0 ).real = src1->COLORSPINOR( 1, 0 ).real + ss * src2->COLORSPINOR( 1, 0 ).real;
    dest->COLORSPINOR( 1, 0 ).imag = src1->COLORSPINOR( 1, 0 ).imag + ss * src2->COLORSPINOR( 1, 0 ).imag;
    dest->COLORSPINOR( 2, 0 ).real = src1->COLORSPINOR( 2, 0 ).real + ss * src2->COLORSPINOR( 2, 0 ).real;
    dest->COLORSPINOR( 2, 0 ).imag = src1->COLORSPINOR( 2, 0 ).imag + ss * src2->COLORSPINOR( 2, 0 ).imag;

    dest->COLORSPINOR( 0, 1 ).real = src1->COLORSPINOR( 0, 1 ).real + ss * src2->COLORSPINOR( 0, 1 ).real;
    dest->COLORSPINOR( 0, 1 ).imag = src1->COLORSPINOR( 0, 1 ).imag + ss * src2->COLORSPINOR( 0, 1 ).imag;
    dest->COLORSPINOR( 1, 1 ).real = src1->COLORSPINOR( 1, 1 ).real + ss * src2->COLORSPINOR( 1, 1 ).real;
    dest->COLORSPINOR( 1, 1 ).imag = src1->COLORSPINOR( 1, 1 ).imag + ss * src2->COLORSPINOR( 1, 1 ).imag;
    dest->COLORSPINOR( 2, 1 ).real = src1->COLORSPINOR( 2, 1 ).real + ss * src2->COLORSPINOR( 2, 1 ).real;
    dest->COLORSPINOR( 2, 1 ).imag = src1->COLORSPINOR( 2, 1 ).imag + ss * src2->COLORSPINOR( 2, 1 ).imag;

    dest->COLORSPINOR( 0, 2 ).real = src1->COLORSPINOR( 0, 2 ).real + ss * src2->COLORSPINOR( 0, 2 ).real;
    dest->COLORSPINOR( 0, 2 ).imag = src1->COLORSPINOR( 0, 2 ).imag + ss * src2->COLORSPINOR( 0, 2 ).imag;
    dest->COLORSPINOR( 1, 2 ).real = src1->COLORSPINOR( 1, 2 ).real + ss * src2->COLORSPINOR( 1, 2 ).real;
    dest->COLORSPINOR( 1, 2 ).imag = src1->COLORSPINOR( 1, 2 ).imag + ss * src2->COLORSPINOR( 1, 2 ).imag;
    dest->COLORSPINOR( 2, 2 ).real = src1->COLORSPINOR( 2, 2 ).real + ss * src2->COLORSPINOR( 2, 2 ).real;
    dest->COLORSPINOR( 2, 2 ).imag = src1->COLORSPINOR( 2, 2 ).imag + ss * src2->COLORSPINOR( 2, 2 ).imag;

    dest->COLORSPINOR( 0, 3 ).real = src1->COLORSPINOR( 0, 3 ).real + ss * src2->COLORSPINOR( 0, 3 ).real;
    dest->COLORSPINOR( 0, 3 ).imag = src1->COLORSPINOR( 0, 3 ).imag + ss * src2->COLORSPINOR( 0, 3 ).imag;
    dest->COLORSPINOR( 1, 3 ).real = src1->COLORSPINOR( 1, 3 ).real + ss * src2->COLORSPINOR( 1, 3 ).real;
    dest->COLORSPINOR( 1, 3 ).imag = src1->COLORSPINOR( 1, 3 ).imag + ss * src2->COLORSPINOR( 1, 3 ).imag;
    dest->COLORSPINOR( 2, 3 ).real = src1->COLORSPINOR( 2, 3 ).real + ss * src2->COLORSPINOR( 2, 3 ).real;
    dest->COLORSPINOR( 2, 3 ).imag = src1->COLORSPINOR( 2, 3 ).imag + ss * src2->COLORSPINOR( 2, 3 ).imag;


}


// version of the above ported to targetDP

__target__ void scalar_mult_add_wvec_tdp( double * src1, double * src2, double s, double * dest, int isite )
{

    register double ss;
    ss = s;
    int iv=0;

    __targetILP__(iv) dest[WVI(isite+iv,0,0,REPART)] = src1[WVI(isite+iv,0,0,REPART)] + ss * src2[WVI(isite+iv,0,0,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,0,0,IMPART)] = src1[WVI(isite+iv,0,0,IMPART)] + ss * src2[WVI(isite+iv,0,0,IMPART)];
    __targetILP__(iv) dest[WVI(isite+iv,1,0,REPART)] = src1[WVI(isite+iv,1,0,REPART)] + ss * src2[WVI(isite+iv,1,0,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,1,0,IMPART)] = src1[WVI(isite+iv,1,0,IMPART)] + ss * src2[WVI(isite+iv,1,0,IMPART)];
    __targetILP__(iv) dest[WVI(isite+iv,2,0,REPART)] = src1[WVI(isite+iv,2,0,REPART)] + ss * src2[WVI(isite+iv,2,0,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,2,0,IMPART)] = src1[WVI(isite+iv,2,0,IMPART)] + ss * src2[WVI(isite+iv,2,0,IMPART)];

    __targetILP__(iv) dest[WVI(isite+iv,0,1,REPART)] = src1[WVI(isite+iv,0,1,REPART)] + ss * src2[WVI(isite+iv,0,1,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,0,1,IMPART)] = src1[WVI(isite+iv,0,1,IMPART)] + ss * src2[WVI(isite+iv,0,1,IMPART)];
    __targetILP__(iv) dest[WVI(isite+iv,1,1,REPART)] = src1[WVI(isite+iv,1,1,REPART)] + ss * src2[WVI(isite+iv,1,1,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,1,1,IMPART)] = src1[WVI(isite+iv,1,1,IMPART)] + ss * src2[WVI(isite+iv,1,1,IMPART)];
    __targetILP__(iv) dest[WVI(isite+iv,2,1,REPART)] = src1[WVI(isite+iv,2,1,REPART)] + ss * src2[WVI(isite+iv,2,1,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,2,1,IMPART)] = src1[WVI(isite+iv,2,1,IMPART)] + ss * src2[WVI(isite+iv,2,1,IMPART)];

    __targetILP__(iv) dest[WVI(isite+iv,0,2,REPART)] = src1[WVI(isite+iv,0,2,REPART)] + ss * src2[WVI(isite+iv,0,2,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,0,2,IMPART)] = src1[WVI(isite+iv,0,2,IMPART)] + ss * src2[WVI(isite+iv,0,2,IMPART)];
    __targetILP__(iv) dest[WVI(isite+iv,1,2,REPART)] = src1[WVI(isite+iv,1,2,REPART)] + ss * src2[WVI(isite+iv,1,2,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,1,2,IMPART)] = src1[WVI(isite+iv,1,2,IMPART)] + ss * src2[WVI(isite+iv,1,2,IMPART)];
    __targetILP__(iv) dest[WVI(isite+iv,2,2,REPART)] = src1[WVI(isite+iv,2,2,REPART)] + ss * src2[WVI(isite+iv,2,2,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,2,2,IMPART)] = src1[WVI(isite+iv,2,2,IMPART)] + ss * src2[WVI(isite+iv,2,2,IMPART)];

    __targetILP__(iv) dest[WVI(isite+iv,0,3,REPART)] = src1[WVI(isite+iv,0,3,REPART)] + ss * src2[WVI(isite+iv,0,3,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,0,3,IMPART)] = src1[WVI(isite+iv,0,3,IMPART)] + ss * src2[WVI(isite+iv,0,3,IMPART)];
    __targetILP__(iv) dest[WVI(isite+iv,1,3,REPART)] = src1[WVI(isite+iv,1,3,REPART)] + ss * src2[WVI(isite+iv,1,3,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,1,3,IMPART)] = src1[WVI(isite+iv,1,3,IMPART)] + ss * src2[WVI(isite+iv,1,3,IMPART)];
    __targetILP__(iv) dest[WVI(isite+iv,2,3,REPART)] = src1[WVI(isite+iv,2,3,REPART)] + ss * src2[WVI(isite+iv,2,3,REPART)];
    __targetILP__(iv) dest[WVI(isite+iv,2,3,IMPART)] = src1[WVI(isite+iv,2,3,IMPART)] + ss * src2[WVI(isite+iv,2,3,IMPART)];
    

}

void scalar2_mult_add_wvec( wilson_vector * src1, double t, wilson_vector * src2, double s, wilson_vector * dest )
{

    register double ss;
    ss = s;
    register double tt;
    tt = t;

    dest->COLORSPINOR( 0, 0 ).real = tt * src1->COLORSPINOR( 0, 0 ).real + ss * src2->COLORSPINOR( 0, 0 ).real;
    dest->COLORSPINOR( 0, 0 ).imag = tt * src1->COLORSPINOR( 0, 0 ).imag + ss * src2->COLORSPINOR( 0, 0 ).imag;
    dest->COLORSPINOR( 1, 0 ).real = tt * src1->COLORSPINOR( 1, 0 ).real + ss * src2->COLORSPINOR( 1, 0 ).real;
    dest->COLORSPINOR( 1, 0 ).imag = tt * src1->COLORSPINOR( 1, 0 ).imag + ss * src2->COLORSPINOR( 1, 0 ).imag;
    dest->COLORSPINOR( 2, 0 ).real = tt * src1->COLORSPINOR( 2, 0 ).real + ss * src2->COLORSPINOR( 2, 0 ).real;
    dest->COLORSPINOR( 2, 0 ).imag = tt * src1->COLORSPINOR( 2, 0 ).imag + ss * src2->COLORSPINOR( 2, 0 ).imag;

    dest->COLORSPINOR( 0, 1 ).real = tt * src1->COLORSPINOR( 0, 1 ).real + ss * src2->COLORSPINOR( 0, 1 ).real;
    dest->COLORSPINOR( 0, 1 ).imag = tt * src1->COLORSPINOR( 0, 1 ).imag + ss * src2->COLORSPINOR( 0, 1 ).imag;
    dest->COLORSPINOR( 1, 1 ).real = tt * src1->COLORSPINOR( 1, 1 ).real + ss * src2->COLORSPINOR( 1, 1 ).real;
    dest->COLORSPINOR( 1, 1 ).imag = tt * src1->COLORSPINOR( 1, 1 ).imag + ss * src2->COLORSPINOR( 1, 1 ).imag;
    dest->COLORSPINOR( 2, 1 ).real = tt * src1->COLORSPINOR( 2, 1 ).real + ss * src2->COLORSPINOR( 2, 1 ).real;
    dest->COLORSPINOR( 2, 1 ).imag = tt * src1->COLORSPINOR( 2, 1 ).imag + ss * src2->COLORSPINOR( 2, 1 ).imag;

    dest->COLORSPINOR( 0, 2 ).real = tt * src1->COLORSPINOR( 0, 2 ).real + ss * src2->COLORSPINOR( 0, 2 ).real;
    dest->COLORSPINOR( 0, 2 ).imag = tt * src1->COLORSPINOR( 0, 2 ).imag + ss * src2->COLORSPINOR( 0, 2 ).imag;
    dest->COLORSPINOR( 1, 2 ).real = tt * src1->COLORSPINOR( 1, 2 ).real + ss * src2->COLORSPINOR( 1, 2 ).real;
    dest->COLORSPINOR( 1, 2 ).imag = tt * src1->COLORSPINOR( 1, 2 ).imag + ss * src2->COLORSPINOR( 1, 2 ).imag;
    dest->COLORSPINOR( 2, 2 ).real = tt * src1->COLORSPINOR( 2, 2 ).real + ss * src2->COLORSPINOR( 2, 2 ).real;
    dest->COLORSPINOR( 2, 2 ).imag = tt * src1->COLORSPINOR( 2, 2 ).imag + ss * src2->COLORSPINOR( 2, 2 ).imag;

    dest->COLORSPINOR( 0, 3 ).real = tt * src1->COLORSPINOR( 0, 3 ).real + ss * src2->COLORSPINOR( 0, 3 ).real;
    dest->COLORSPINOR( 0, 3 ).imag = tt * src1->COLORSPINOR( 0, 3 ).imag + ss * src2->COLORSPINOR( 0, 3 ).imag;
    dest->COLORSPINOR( 1, 3 ).real = tt * src1->COLORSPINOR( 1, 3 ).real + ss * src2->COLORSPINOR( 1, 3 ).real;
    dest->COLORSPINOR( 1, 3 ).imag = tt * src1->COLORSPINOR( 1, 3 ).imag + ss * src2->COLORSPINOR( 1, 3 ).imag;
    dest->COLORSPINOR( 2, 3 ).real = tt * src1->COLORSPINOR( 2, 3 ).real + ss * src2->COLORSPINOR( 2, 3 ).real;
    dest->COLORSPINOR( 2, 3 ).imag = tt * src1->COLORSPINOR( 2, 3 ).imag + ss * src2->COLORSPINOR( 2, 3 ).imag;

}

void scalar3_mult_add_wvec( wilson_vector * src1, double t, 
        wilson_vector * src2, double s, 
        wilson_vector * src3, double u, 
        wilson_vector * dest )
{

    register double ss;
    ss = s;
    register double tt;
    tt = t;
    register double uu;
    uu = u;

    dest->COLORSPINOR( 0, 0 ).real = tt * src1->COLORSPINOR( 0, 0 ).real + ss * src2->COLORSPINOR( 0, 0 ).real+ uu * src3->COLORSPINOR( 0, 0 ).real;
    dest->COLORSPINOR( 0, 0 ).imag = tt * src1->COLORSPINOR( 0, 0 ).imag + ss * src2->COLORSPINOR( 0, 0 ).imag+ uu * src3->COLORSPINOR( 0, 0 ).imag;
    dest->COLORSPINOR( 1, 0 ).real = tt * src1->COLORSPINOR( 1, 0 ).real + ss * src2->COLORSPINOR( 1, 0 ).real+ uu * src3->COLORSPINOR( 1, 0 ).real;
    dest->COLORSPINOR( 1, 0 ).imag = tt * src1->COLORSPINOR( 1, 0 ).imag + ss * src2->COLORSPINOR( 1, 0 ).imag+ uu * src3->COLORSPINOR( 1, 0 ).imag;
    dest->COLORSPINOR( 2, 0 ).real = tt * src1->COLORSPINOR( 2, 0 ).real + ss * src2->COLORSPINOR( 2, 0 ).real+ uu * src3->COLORSPINOR( 2, 0 ).real;
    dest->COLORSPINOR( 2, 0 ).imag = tt * src1->COLORSPINOR( 2, 0 ).imag + ss * src2->COLORSPINOR( 2, 0 ).imag+ uu * src3->COLORSPINOR( 2, 0 ).imag;
                                                                                                                                                   
    dest->COLORSPINOR( 0, 1 ).real = tt * src1->COLORSPINOR( 0, 1 ).real + ss * src2->COLORSPINOR( 0, 1 ).real+ uu * src3->COLORSPINOR( 0, 1 ).real;
    dest->COLORSPINOR( 0, 1 ).imag = tt * src1->COLORSPINOR( 0, 1 ).imag + ss * src2->COLORSPINOR( 0, 1 ).imag+ uu * src3->COLORSPINOR( 0, 1 ).imag;
    dest->COLORSPINOR( 1, 1 ).real = tt * src1->COLORSPINOR( 1, 1 ).real + ss * src2->COLORSPINOR( 1, 1 ).real+ uu * src3->COLORSPINOR( 1, 1 ).real;
    dest->COLORSPINOR( 1, 1 ).imag = tt * src1->COLORSPINOR( 1, 1 ).imag + ss * src2->COLORSPINOR( 1, 1 ).imag+ uu * src3->COLORSPINOR( 1, 1 ).imag;
    dest->COLORSPINOR( 2, 1 ).real = tt * src1->COLORSPINOR( 2, 1 ).real + ss * src2->COLORSPINOR( 2, 1 ).real+ uu * src3->COLORSPINOR( 2, 1 ).real;
    dest->COLORSPINOR( 2, 1 ).imag = tt * src1->COLORSPINOR( 2, 1 ).imag + ss * src2->COLORSPINOR( 2, 1 ).imag+ uu * src3->COLORSPINOR( 2, 1 ).imag;
                                                                                                                                                   
    dest->COLORSPINOR( 0, 2 ).real = tt * src1->COLORSPINOR( 0, 2 ).real + ss * src2->COLORSPINOR( 0, 2 ).real+ uu * src3->COLORSPINOR( 0, 2 ).real;
    dest->COLORSPINOR( 0, 2 ).imag = tt * src1->COLORSPINOR( 0, 2 ).imag + ss * src2->COLORSPINOR( 0, 2 ).imag+ uu * src3->COLORSPINOR( 0, 2 ).imag;
    dest->COLORSPINOR( 1, 2 ).real = tt * src1->COLORSPINOR( 1, 2 ).real + ss * src2->COLORSPINOR( 1, 2 ).real+ uu * src3->COLORSPINOR( 1, 2 ).real;
    dest->COLORSPINOR( 1, 2 ).imag = tt * src1->COLORSPINOR( 1, 2 ).imag + ss * src2->COLORSPINOR( 1, 2 ).imag+ uu * src3->COLORSPINOR( 1, 2 ).imag;
    dest->COLORSPINOR( 2, 2 ).real = tt * src1->COLORSPINOR( 2, 2 ).real + ss * src2->COLORSPINOR( 2, 2 ).real+ uu * src3->COLORSPINOR( 2, 2 ).real;
    dest->COLORSPINOR( 2, 2 ).imag = tt * src1->COLORSPINOR( 2, 2 ).imag + ss * src2->COLORSPINOR( 2, 2 ).imag+ uu * src3->COLORSPINOR( 2, 2 ).imag;
                                                                                                                                                   
    dest->COLORSPINOR( 0, 3 ).real = tt * src1->COLORSPINOR( 0, 3 ).real + ss * src2->COLORSPINOR( 0, 3 ).real+ ss * src3->COLORSPINOR( 0, 3 ).real;
    dest->COLORSPINOR( 0, 3 ).imag = tt * src1->COLORSPINOR( 0, 3 ).imag + ss * src2->COLORSPINOR( 0, 3 ).imag+ ss * src3->COLORSPINOR( 0, 3 ).imag;
    dest->COLORSPINOR( 1, 3 ).real = tt * src1->COLORSPINOR( 1, 3 ).real + ss * src2->COLORSPINOR( 1, 3 ).real+ ss * src3->COLORSPINOR( 1, 3 ).real;
    dest->COLORSPINOR( 1, 3 ).imag = tt * src1->COLORSPINOR( 1, 3 ).imag + ss * src2->COLORSPINOR( 1, 3 ).imag+ ss * src3->COLORSPINOR( 1, 3 ).imag;
    dest->COLORSPINOR( 2, 3 ).real = tt * src1->COLORSPINOR( 2, 3 ).real + ss * src2->COLORSPINOR( 2, 3 ).real+ ss * src3->COLORSPINOR( 2, 3 ).real;
    dest->COLORSPINOR( 2, 3 ).imag = tt * src1->COLORSPINOR( 2, 3 ).imag + ss * src2->COLORSPINOR( 2, 3 ).imag+ ss * src3->COLORSPINOR( 2, 3 ).imag;

}
