Esempio n. 1
0
// this actually applies the preconditioned dslash, e.g., D_ee^{-1} D_eo or D_oo^{-1} D_oe
void wil_dslash(void *out, void **gauge, void *in, int oddBit, int daggerBit,
		QudaPrecision precision, QudaGaugeParam &gauge_param) {
  
#ifndef MULTI_GPU  
  if (precision == QUDA_DOUBLE_PRECISION)
    dslashReference((double*)out, (double**)gauge, (double*)in, oddBit, daggerBit);
  else
    dslashReference((float*)out, (float**)gauge, (float*)in, oddBit, daggerBit);
#else

  GaugeFieldParam gauge_field_param(gauge, gauge_param);
  cpuGaugeField cpu(gauge_field_param);
  cpu.exchangeGhost();
  void **ghostGauge = (void**)cpu.Ghost();

  // Get spinor ghost fields
  // First wrap the input spinor into a ColorSpinorField
  ColorSpinorParam csParam;
  csParam.v = in;
  csParam.fieldLocation = QUDA_CPU_FIELD_LOCATION;
  csParam.nColor = 3;
  csParam.nSpin = 4;
  csParam.nDim = 4;
  for (int d=0; d<4; d++) csParam.x[d] = Z[d];
  csParam.precision = precision;
  csParam.pad = 0;
  csParam.siteSubset = QUDA_PARITY_SITE_SUBSET;
  csParam.x[0] /= 2;
  csParam.siteOrder = QUDA_EVEN_ODD_SITE_ORDER;
  csParam.fieldOrder = QUDA_SPACE_SPIN_COLOR_FIELD_ORDER;
  csParam.gammaBasis = QUDA_DEGRAND_ROSSI_GAMMA_BASIS;
  csParam.create = QUDA_REFERENCE_FIELD_CREATE;
  
  cpuColorSpinorField inField(csParam);

  {  // Now do the exchange
    QudaParity otherParity = QUDA_INVALID_PARITY;
    if (oddBit == QUDA_EVEN_PARITY) otherParity = QUDA_ODD_PARITY;
    else if (oddBit == QUDA_ODD_PARITY) otherParity = QUDA_EVEN_PARITY;
    else errorQuda("ERROR: full parity not supported in function %s", __FUNCTION__);

    int nFace = 1;
    FaceBuffer faceBuf(Z, 4, mySpinorSiteSize, nFace, precision);
    faceBuf.exchangeCpuSpinor(inField, otherParity, daggerBit); 
  }
  void** fwd_nbr_spinor = inField.fwdGhostFaceBuffer;
  void** back_nbr_spinor = inField.backGhostFaceBuffer;

  if (precision == QUDA_DOUBLE_PRECISION) {
    dslashReference((double*)out, (double**)gauge, (double**)ghostGauge, (double*)in, 
		    (double**)fwd_nbr_spinor, (double**)back_nbr_spinor, oddBit, daggerBit);
  } else{
    dslashReference((float*)out, (float**)gauge, (float**)ghostGauge, (float*)in, 
		    (float**)fwd_nbr_spinor, (float**)back_nbr_spinor, oddBit, daggerBit);
  }

#endif

}
Esempio n. 2
0
// Apply the even-odd preconditioned Dirac operator
void MatPCDag(float *outEven, float **gauge, float *inEven, float kappa) {
    float *tmpOdd = (float*)malloc(Nh*spinorSiteSize*sizeof(float));
    
    // full dslash operator
    dslashReference(tmpOdd, gauge, inEven, 1, 1);
    dslashReference(outEven, gauge, tmpOdd, 0, 1);
    
    float kappa2 = -kappa*kappa;
    xpay(inEven, kappa2, outEven, Nh*spinorSiteSize);
    free(tmpOdd);
}
Esempio n. 3
0
void MatDag(float *out, float **gauge, float *in, float kappa) {
    float *inEven = in;
    float *inOdd  = in + Nh*spinorSiteSize;
    float *outEven = out;
    float *outOdd = out + Nh*spinorSiteSize;
    
    // full dslash operator
    dslashReference(outOdd, gauge, inEven, 1, 1);
    dslashReference(outEven, gauge, inOdd, 0, 1);
    
    // lastly apply the kappa term
    xpay(in, -kappa, out, N*spinorSiteSize);
}
Esempio n. 4
0
void cgTest() {
  float mass = 0.01;
  float kappa = 1.0 / (2.0*(4 + mass));

  float *gauge[4];
  for (int dir = 0; dir < 4; dir++) {
    gauge[dir] = (float*)malloc(N*gaugeSiteSize*sizeof(float));
  }
  //constructGaugeField(gauge);
  constructUnitGaugeField(gauge);
    
  float *spinorIn = (float*)malloc(N*spinorSiteSize*sizeof(float));
  float *spinorOut = (float*)malloc(N*spinorSiteSize*sizeof(float));

#ifdef EVEN_ODD
  float *source = (float *)malloc(Nh*spinorSiteSize*sizeof(float));
  float *tmp = (float *)malloc(Nh*spinorSiteSize*sizeof(float));
#else
  float *source = (float *)malloc(N*spinorSiteSize*sizeof(float));
#endif

  int i0 = 0;
  int s0 = 0;
  int c0 = 0;
  constructPointSpinorField(spinorIn, i0, s0, c0);
  //constructSpinorField(spinorIn);

  // Prepare the source term
  ax(2*kappa, spinorIn, N*spinorSiteSize);

  // see output element
  // Mat(source, gauge, spinorIn, kappa);
  // printSpinorElement(source, 0);

#ifdef EVEN_ODD
  float *spinorInOdd = spinorIn + Nh*spinorSiteSize;
  dslashReference(tmp, gauge, spinorInOdd, 0, 0);
  xpay(spinorIn, kappa, tmp, Nh*spinorSiteSize);
  MatPCDag(source, gauge, tmp, kappa);
#else
  MatDag(source, gauge, spinorIn, kappa);
#endif

  cgCuda(spinorOut, gauge, source, kappa, 1e-7);
//  cg_reference(spinorOut, gauge, source, kappa, 1e-7);

  // Reconstruct the full inverse
#ifdef EVEN_ODD
  float *spinorOutOdd = spinorOut + Nh*spinorSiteSize;
  dslashReference(spinorOutOdd, gauge, spinorOut, 1, 0);
  xpay(spinorInOdd, kappa, spinorOutOdd, Nh*spinorSiteSize);
#endif

  printf("Result norm = %e\n", norm(spinorOut, N*spinorSiteSize));

  // release memory
  for (int dir = 0; dir < 4; dir++) free(gauge[dir]);
  free(source);
#ifdef EVEN_ODD
  free(tmp);
#endif
  free(spinorIn);
  free(spinorOut);
}