CHROMA
syssolver_linop_nef_quda_w.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! \file
3 * \brief Solve a MdagM*psi=chi linear system by BiCGStab
4 */
5 
6 #ifndef __syssolver_linop_quda_nef_h__
7 #define __syssolver_linop_quda_nef_h__
8 
9 #include "chroma_config.h"
10 
11 #ifdef BUILD_QUDA
12 #include <quda.h>
13 
14 #include "handle.h"
15 #include "state.h"
16 #include "syssolver.h"
17 #include "linearop.h"
23 #include <string>
24 
25 #include "util/gauge/reunit.h"
26 
27 //#include <util_quda.h>
28 #ifdef QDP_IS_QDPJIT
30 #endif
31 
32 namespace Chroma
33 {
34 
35  //! Richardson system solver namespace
36  namespace LinOpSysSolverQUDANEFEnv
37  {
38  //! Register the syssolver
39  bool registerAll();
40  }
41 
42 
43 
44  //! Solve a Clover Fermion System using the QUDA inverter
45  /*! \ingroup invert
46  * WARNING THIS SOLVER WORKS FOR MOEBIUS/DWF ONLY ***
47  */
48 
49  class LinOpSysSolverQUDANEF : public LinOpSystemSolverArray<LatticeFermion>
50  {
51  public:
52  typedef LatticeFermion T;
53  typedef LatticeColorMatrix U;
54  typedef multi1d<LatticeColorMatrix> Q;
55 
56  typedef LatticeFermionF TF;
57  typedef LatticeColorMatrixF UF;
58  typedef multi1d<LatticeColorMatrixF> QF;
59 
60  typedef LatticeFermionF TD;
61  typedef LatticeColorMatrixF UD;
62  typedef multi1d<LatticeColorMatrixF> QD;
63 
64  typedef WordType<T>::Type_t REALT;
65  //! Constructor
66  /*!
67  * \param M_ Linear operator ( Read )
68  * \param invParam inverter parameters ( Read )
69  */
70  LinOpSysSolverQUDANEF(Handle< LinearOperatorArray<T> > A_,
71  Handle< FermState<T,Q,Q> > state_,
72  const SysSolverQUDANEFParams& invParam_) :
73  A(A_), invParam(invParam_)
74  {
75  START_CODE();
76 
77  QDPIO::cout << "LinOpSysSolverQUDANEF:" << std::endl;
78 
79  // FOLLOWING INITIALIZATION in test QUDA program
80 
81  // 1) work out cpu_prec, cuda_prec, cuda_prec_sloppy
82  int s = sizeof( WordType<T>::Type_t );
83 
84  if (s == 4) {
85  cpu_prec = QUDA_SINGLE_PRECISION;
86  }
87  else {
88  cpu_prec = QUDA_DOUBLE_PRECISION;
89  }
90 
91 
92  // Work out GPU precision
93  switch( invParam.cudaPrecision ) {
94  case HALF:
95  gpu_prec = QUDA_HALF_PRECISION;
96  break;
97  case SINGLE:
98  gpu_prec = QUDA_SINGLE_PRECISION;
99  break;
100  case DOUBLE:
101  gpu_prec = QUDA_DOUBLE_PRECISION;
102  break;
103  default:
104  gpu_prec = cpu_prec;
105  break;
106  }
107 
108  // Work out GPU Sloppy precision
109  // Default: No Sloppy
110  switch( invParam.cudaSloppyPrecision ) {
111  case HALF:
112  gpu_half_prec = QUDA_HALF_PRECISION;
113  break;
114  case SINGLE:
115  gpu_half_prec = QUDA_SINGLE_PRECISION;
116  break;
117  case DOUBLE:
118  gpu_half_prec = QUDA_DOUBLE_PRECISION;
119  break;
120  default:
121  gpu_half_prec = gpu_prec;
122  break;
123  }
124 
125  // 2) pull 'new; GAUGE and Invert params
126  q_gauge_param = newQudaGaugeParam();
127  quda_inv_param = newQudaInvertParam();
128 
129  // 3) set lattice size
130  const multi1d<int>& latdims = Layout::subgridLattSize();
131 
132  q_gauge_param.X[0] = latdims[0];
133  q_gauge_param.X[1] = latdims[1];
134  q_gauge_param.X[2] = latdims[2];
135  q_gauge_param.X[3] = latdims[3];
136 
137  // 5) - set QUDA_WILSON_LINKS, QUDA_GAUGE_ORDER
138  q_gauge_param.type = QUDA_WILSON_LINKS;
139 #ifndef BUILD_QUDA_DEVIFACE_GAUGE
140  q_gauge_param.gauge_order = QUDA_QDP_GAUGE_ORDER; // gauge[mu], p
141 #else
142  QDPIO::cout << "MDAGM Using QDP-JIT gauge order" << std::endl;
143  q_gauge_param.location = QUDA_CUDA_FIELD_LOCATION;
144  q_gauge_param.gauge_order = QUDA_QDPJIT_GAUGE_ORDER;
145 #endif
146 
147  // 6) - set t_boundary
148  // Convention: BC has to be applied already
149  // This flag just tells QUDA that this is so,
150  // so that QUDA can take care in the reconstruct
151  if( invParam.AntiPeriodicT ) {
152  q_gauge_param.t_boundary = QUDA_ANTI_PERIODIC_T;
153  }
154  else {
155  q_gauge_param.t_boundary = QUDA_PERIODIC_T;
156  }
157 
158  // Set cpu_prec, cuda_prec, reconstruct and sloppy versions
159  q_gauge_param.cpu_prec = cpu_prec;
160  q_gauge_param.cuda_prec = gpu_prec;
161 
162 
163  switch( invParam.cudaReconstruct ) {
164  case RECONS_NONE:
165  q_gauge_param.reconstruct = QUDA_RECONSTRUCT_NO;
166  break;
167  case RECONS_8:
168  q_gauge_param.reconstruct = QUDA_RECONSTRUCT_8;
169  break;
170  case RECONS_12:
171  q_gauge_param.reconstruct = QUDA_RECONSTRUCT_12;
172  break;
173  default:
174  q_gauge_param.reconstruct = QUDA_RECONSTRUCT_12;
175  break;
176  };
177 
178  q_gauge_param.cuda_prec_sloppy = gpu_half_prec;
179 
180  switch( invParam.cudaSloppyReconstruct ) {
181  case RECONS_NONE:
182  q_gauge_param.reconstruct_sloppy = QUDA_RECONSTRUCT_NO;
183  break;
184  case RECONS_8:
185  q_gauge_param.reconstruct_sloppy = QUDA_RECONSTRUCT_8;
186  break;
187  case RECONS_12:
188  q_gauge_param.reconstruct_sloppy = QUDA_RECONSTRUCT_12;
189  break;
190  default:
191  q_gauge_param.reconstruct_sloppy = QUDA_RECONSTRUCT_12;
192  break;
193  };
194 
195  // Gauge fixing:
196 
197  // These are the links
198  // They may be smeared and the BC's may be applied
199  Q links_single(Nd);
200 
201  // Now downcast to single prec fields.
202  for(int mu=0; mu < Nd; mu++) {
203  links_single[mu] = (state_->getLinks())[mu];
204  }
205 
206  // GaugeFix
207  if( invParam.axialGaugeP ) {
208  QDPIO::cout << "Fixing Temporal Gauge" << std::endl;
209  temporalGauge(links_single, GFixMat, Nd-1);
210  for(int mu=0; mu < Nd; mu++){
211  links_single[mu] = GFixMat*(state_->getLinks())[mu]*adj(shift(GFixMat, FORWARD, mu));
212  }
213  q_gauge_param.gauge_fix = QUDA_GAUGE_FIXED_YES;
214  }
215  else {
216  // No GaugeFix
217  q_gauge_param.gauge_fix = QUDA_GAUGE_FIXED_NO; // No Gfix yet
218  }
219 
220  // Don't support anisotorpy for Moebius
221  q_gauge_param.anisotropy = 1.0;
222 
223  // Now onto the inv param:
224  // Dslash type
225  quda_inv_param.dslash_type = QUDA_MOBIUS_DWF_DSLASH;
226  // Invert type:
227  switch( invParam.solverType ) {
228  case CG:
229  quda_inv_param.inv_type = QUDA_CG_INVERTER;
230  solver_string = "CG";
231  break;
232  case BICGSTAB:
233  QDPIO::cerr << "Solver BICGSTAB not supported for MDWF" << std::endl;
234  QDP_abort(1);
235  break;
236  case GCR:
237  QDPIO::cerr << "Solver GCR not supported for MDWF" << std::endl;
238  QDP_abort(1);
239  break;
240  default:
241  QDPIO::cerr << "Unknown Solver type" << std::endl;
242  QDP_abort(1);
243  break;
244  }
245 
246  // Mass
247  quda_inv_param.mass = toDouble(invParam.NEFParams.Mass);
248  quda_inv_param.m5=toDouble(-invParam.NEFParams.OverMass);
249  quda_inv_param.Ls=invParam.NEFParams.N5;
250  // Mike made these static so no need to alloc them.
251  if ( invParam.NEFParams.N5 >= QUDA_MAX_DWF_LS ) {
252  QDPIO::cerr << "LS can be at most " << QUDA_MAX_DWF_LS << std::endl;
253  QDP_abort(1);
254  }
255 
256  // Copy b5 and c5 into static array
257  QDPIO::cout << "Ls from matrix: " << A->size() << std::endl;
258  QDPIO::cout << "Ls from params: " << invParam.NEFParams.N5 << std::endl;
259  QDPIO::cout << "Ls from quda: " << quda_inv_param.Ls << std::endl;
260  for(int s = 0; s < quda_inv_param.Ls; s++){
261  quda_inv_param.b_5[s] = toDouble(invParam.NEFParams.b5[s]);
262  quda_inv_param.c_5[s] = toDouble(invParam.NEFParams.c5[s]);
263  QDPIO::cout << " b5[" <<s<<"] = " << quda_inv_param.b_5[s] << " c5[" << s << "] = " << quda_inv_param.c_5[s] << std::endl;
264  }
265 
266  quda_inv_param.tol = toDouble(invParam.RsdTarget);
267  quda_inv_param.maxiter = invParam.MaxIter;
268  quda_inv_param.reliable_delta = toDouble(invParam.Delta);
269  quda_inv_param.pipeline = invParam.Pipeline;
270 
271  // Solution type
272  quda_inv_param.solution_type = QUDA_MATPC_SOLUTION;
273 
274  // Solve type, only CG-types supported so far:
275  switch( invParam.solverType ) {
276  case CG:
277  if( invParam.cgnrP ) {
278  QDPIO::cout << "Doing CGNR solve" << std::endl;
279  quda_inv_param.solve_type = QUDA_NORMOP_PC_SOLVE;
280  }
281  else {
282  QDPIO::cout << "Doing CGNE solve" << std::endl;
283  quda_inv_param.solve_type = QUDA_NORMERR_PC_SOLVE;
284  }
285 
286  break;
287 
288  default:
289  if( invParam.cgnrP ) {
290  QDPIO::cout << "Doing CGNR solve" << std::endl;
291  quda_inv_param.solve_type = QUDA_NORMOP_PC_SOLVE;
292  }
293  else {
294  QDPIO::cout << "Doing CGNE solve" << std::endl;
295  quda_inv_param.solve_type = QUDA_NORMERR_PC_SOLVE;
296  }
297 
298 
299  break;
300  }
301 
302  //only symmetric DWF supported at the moment:
303  QDPIO::cout << "Using Symmetric Linop: A_oo - D_oe A^{-1}_ee D_eo" << std::endl;
304  quda_inv_param.matpc_type = QUDA_MATPC_ODD_ODD_ASYMMETRIC;
305  quda_inv_param.dagger = QUDA_DAG_NO;
306  quda_inv_param.mass_normalization = QUDA_KAPPA_NORMALIZATION;
307  quda_inv_param.cpu_prec = cpu_prec;
308  quda_inv_param.cuda_prec = gpu_prec;
309  quda_inv_param.cuda_prec_sloppy = gpu_half_prec;
310  quda_inv_param.preserve_source = QUDA_PRESERVE_SOURCE_NO;
311  quda_inv_param.gamma_basis = QUDA_DEGRAND_ROSSI_GAMMA_BASIS;
312 
313 #ifndef BUILD_QUDA_DEVIFACE_SPINOR
314  quda_inv_param.dirac_order = QUDA_DIRAC_ORDER;
315 #else
316  QDPIO::cout << "MDAGM Using QDP-JIT spinor order" << std::endl;
317  quda_inv_param.dirac_order = QUDA_QDPJIT_DIRAC_ORDER;
318  quda_inv_param.input_location = QUDA_CUDA_FIELD_LOCATION;
319  quda_inv_param.output_location = QUDA_CUDA_FIELD_LOCATION;
320 #endif
321 
322  // Autotuning
323  if( invParam.tuneDslashP ) {
324  QDPIO::cout << "Enabling Dslash Autotuning" << std::endl;
325  quda_inv_param.tune = QUDA_TUNE_YES;
326  }
327  else {
328  QDPIO::cout << "Disabling Dslash Autotuning" << std::endl;
329  quda_inv_param.tune = QUDA_TUNE_NO;
330  }
331 
332 
333  // Setup padding
334  multi1d<int> face_size(4);
335  face_size[0] = latdims[1]*latdims[2]*latdims[3]/2;
336  face_size[1] = latdims[0]*latdims[2]*latdims[3]/2;
337  face_size[2] = latdims[0]*latdims[1]*latdims[3]/2;
338  face_size[3] = latdims[0]*latdims[1]*latdims[2]/2;
339 
340  int max_face = face_size[0];
341  for(int i=1; i < 4; i++) {
342  if ( face_size[i] > max_face ) {
343  max_face = face_size[i];
344  }
345  }
346 
347  q_gauge_param.ga_pad = max_face;
348  // PADDING
349  quda_inv_param.sp_pad = 0;
350  quda_inv_param.cl_pad = 0;
351 
352  QDPIO::cout << "Setting Precondition stuff to defaults for not using" << std::endl;
353  quda_inv_param.inv_type_precondition= QUDA_INVALID_INVERTER;
354  quda_inv_param.tol_precondition = 1.0e-1;
355  quda_inv_param.maxiter_precondition = 1000;
356  quda_inv_param.verbosity_precondition = QUDA_SILENT;
357  quda_inv_param.gcrNkrylov = 1;
358 
359 
360  if( invParam.verboseP ) {
361  quda_inv_param.verbosity = QUDA_VERBOSE;
362  }
363  else {
364  quda_inv_param.verbosity = QUDA_SUMMARIZE;
365  }
366 
367  // Set up the links
368  void* gauge[4];
369 
370 #ifndef BUILD_QUDA_DEVIFACE_GAUGE
371  for(int mu=0; mu < Nd; mu++) {
372  gauge[mu] = (void *)&(links_single[mu].elem(all.start()).elem().elem(0,0).real());
373  }
374 #else
375  GetMemoryPtrGauge(gauge,links_single);
376  //gauge[mu] = GetMemoryPtr( links_single[mu].getId() );
377  //std::cout << "MDAGM CUDA gauge[" << mu << "] in = " << gauge[mu] << "\n";
378 #endif
379 
380  loadGaugeQuda((void *)gauge, &q_gauge_param);
381 
382  END_CODE();
383  }
384 
385 
386  //! Destructor is automatic
387  ~LinOpSysSolverQUDANEF()
388  {
389  QDPIO::cout << "Destructing" << std::endl;
390  freeGaugeQuda();
391  }
392 
393  //! Return the subset on which the operator acts
394  const Subset& subset() const {return A->subset();}
395 
396  //return the size:
397  int size() const {return invParam.NEFParams.N5;}
398 
399  //! Solver the linear system
400  /*!
401  * \param psi solution ( Modify )
402  * \param chi source ( Read )
403  * \return syssolver results
404  */
405  SystemSolverResults_t operator() (multi1d<T>& psi, const multi1d<T>& chi) const
406  {
407  SystemSolverResults_t res;
408 
409  START_CODE();
410  StopWatch swatch;
411  swatch.start();
412 
413 
414 
415  // 1/( 2 kappa_b ) = b5 * ( Nd - M5 ) + 1
416  Real invTwoKappaB = invParam.NEFParams.b5[0]*( Nd - invParam.NEFParams.OverMass) + Real(1);
417  Real twoKappaB = Real(1)/invTwoKappaB;
418 
419 #if 0
420  // Test code....
421  {
422  const multi1d<int>& latdims = Layout::subgridLattSize();
423  int halfsize=latdims[0]*latdims[1]*latdims[2]*latdims[3]/2;
424  int fermsize=halfsize*Nc*Ns*2;
425 
426  // In1 is input to Chroma, Out1 is result
427  multi1d<T> in1( this->size() );
428  multi1d<T> out1(this->size() );
429 
430  // In2 is input to QUDA, Out2 is result
431  multi1d<T> in2( this->size() );
432  multi1d<T> out2(this->size() );
433 
434 
435  for(int s=0; s < this->size(); s++ ) {
436  gaussian(in1[s]); // Gaussian into in1
437  in2[s] = in1[s]; // copy to in2
438 
439  }
440 
441  for(int d=0; d < 2; d++) {
442  for(int s=0; s < this->size(); s++ ) {
443  out1[s]=zero; // zero both out1 and out2
444  out2[s]=zero;
445  }
446 
447  if ( d==0 ) {
448  // Apply A to in2
449  QDPIO::cout << "DOing Mat" << std::endl;
450  (*A)(out2, in2, PLUS);
451  }
452  else {
453  QDPIO::cout << "Doing MatDag" << std::endl;
454  (*A)(out2, in2, MINUS);
455  }
456 
457  // Copy in1 into QUDA
458  REAL* spinorIn = new REAL[quda_inv_param.Ls*fermsize];
459  REAL* spinorOut = new REAL[quda_inv_param.Ls*fermsize];
460  memset((spinorIn), 0, fermsize*quda_inv_param.Ls*sizeof(REAL));
461  memset((spinorOut), 0, fermsize*quda_inv_param.Ls*sizeof(REAL));
462 
463  for(unsigned int s=0; s<quda_inv_param.Ls; s++){
464  memcpy((&spinorIn[fermsize*s]),&(in1[s].elem(rb[1].start()).elem(0).elem(0).real()),fermsize*sizeof(REAL));
465  }
466 
467  // Apply QUDA
468  if( d==0 ) {
469  quda_inv_param.dagger = QUDA_DAG_NO;
470  MatQuda((void *)spinorOut, (void *)spinorIn, (QudaInvertParam*)&quda_inv_param);
471  }
472  else {
473  quda_inv_param.dagger = QUDA_DAG_YES;
474  MatQuda((void *)spinorOut, (void *)spinorIn, (QudaInvertParam*)&quda_inv_param);
475  }
476 
477  for(unsigned int s=0; s<quda_inv_param.Ls; s++){
478  // memset(reinterpret_cast<char*>(&(psi_s[s].elem(all.start()).elem(0).elem(0).real())),0,fermsize*2*sizeof(REAL));
479  memcpy((&out1[s].elem(rb[1].start()).elem(0).elem(0).real()),(&spinorOut[fermsize*s]),fermsize*sizeof(REAL));
480  }
481 
482  // Now compare out1 and out2
483  for(int s=0; s < this->size();s++) {
484  out1[s] *= invTwoKappaB;
485 
486  QDPIO::cout << "s=" << s << " diff=" << norm2(out2[s]-out1[s]) << std::endl;
487  }
488 
489 
490  delete [] spinorIn;
491  delete [] spinorOut;
492  }
493 
494 
495  }
496 #endif
497 
498  QDPIO::cout << "Norm of chi = " << norm2(chi,rb[1]) << std::endl;
499  QDPIO::cout << "TwoKappa = " << twoKappaB << " invTwoKappa_b = " << invTwoKappaB << std::endl;
500 
501  if ( invParam.axialGaugeP ) {
502  multi1d<T> g_chi( this->size());
503  multi1d<T> g_psi( this->size());
504 
505  // Gauge Fix source and initial guess
506  QDPIO::cout << "Gauge Fixing source and initial guess" << std::endl;
507  for(int s=0; s<invParam.NEFParams.N5; s++){
508  g_chi[s][ rb[1] ] = GFixMat * chi[s];
509  g_psi[s][ rb[1] ] = GFixMat * psi[s];
510  }
511  QDPIO::cout << "Solving" << std::endl;
512  res = qudaInvert(g_chi,g_psi);
513  for(int s=0; s < this->size(); s++) {
514  g_psi[s][rb[1]] *= twoKappaB;
515  }
516 
517  QDPIO::cout << "Untransforming solution." << std::endl;
518  for(int s=0; s<invParam.NEFParams.N5; s++){
519  psi[s][ rb[1] ] = adj(GFixMat)*g_psi[s];
520  }
521 
522  }
523  else {
524  QDPIO::cout << "Calling qudaInvert" << std::endl;
525  res = qudaInvert(chi,psi);
526  for(int s=0; s < this->size(); s++) {
527  psi[s][rb[1]] *= twoKappaB;
528  }
529  }
530 
531 
532 
533  swatch.stop();
534 
535  // Check Solution
536  {
537 
538  multi1d<T> r(A->size());
539  multi1d<T> Ax(A->size());
540  r=zero;
541  Ax=zero;
542  Double r_norm(zero);
543  Double b_norm(zero);
544  (*A)(Ax, psi, PLUS);
545  for(int s=0; s < A->size(); s++) {
546  r[s][rb[1]] = chi[s] - Ax[s];
547  r_norm += norm2(r[s], rb[1]);
548  b_norm += norm2(chi[s], rb[1]);
549  }
550 
551  Double resid = sqrt(r_norm);
552  Double rel_resid = sqrt(r_norm/b_norm);
553 
554  res.resid = resid;
555  QDPIO::cout << "QUDA_"<< solver_string <<"_NEF_SOLVER: " << res.n_count << " iterations. Max. Rsd = " << res.resid << " Max. Relative Rsd = " << rel_resid << std::endl;
556 
557 
558  // Convergence Check/Blow Up
559  if ( ! invParam.SilentFailP ) {
560  if ( toBool( rel_resid > invParam.RsdToleranceFactor*invParam.RsdTarget) ) {
561  QDPIO::cerr << "ERROR: QUDA Solver residuum is outside tolerance: QUDA resid="<< rel_resid << " Desired =" << invParam.RsdTarget << " Max Tolerated = " << invParam.RsdToleranceFactor*invParam.RsdTarget << std::endl;
562  QDP_abort(1);
563  }
564 
565  }
566  }
567 
568 
569  END_CODE();
570  return res;
571  }
572 
573  private:
574  // Hide default constructor
575  LinOpSysSolverQUDANEF() {}
576 
577 #if 1
578  Q links_orig;
579 #endif
580 
581  U GFixMat;
582  QudaPrecision_s cpu_prec;
583  QudaPrecision_s gpu_prec;
584  QudaPrecision_s gpu_half_prec;
585 
586  Handle< LinearOperatorArray<T> > A;
587  const SysSolverQUDANEFParams invParam;
588  QudaGaugeParam q_gauge_param;
589  mutable QudaInvertParam quda_inv_param;
590 
591  SystemSolverResults_t qudaInvert(const multi1d<T>& chi_s, multi1d<T>& psi_s)const;
592 
593  std::string solver_string;
594  };
595 
596 
597 } // End namespace
598 
599 #endif // BUILD_QUDA
600 #endif
601 
int mu
Definition: cool.cc:24
4D Even Odd preconditioned NEF domain-wall fermion linear operator
void temporalGauge(multi1d< LatticeColorMatrix > &ug, LatticeColorMatrix &g, int decay_dir)
Temporal gauge fixing.
Class for counted reference semantics.
Linear Operators.
Nd
Definition: meslate.cc:74
bool registerAll()
Register all the factories.
multi1d< Hadron2PtContraction_t > operator()(const multi1d< LatticeColorMatrix > &u)
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
gaussian(aux)
LinOpSysSolverMGProtoClover::Q Q
LinOpSysSolverMGProtoClover::T T
int i
Definition: pbg5p_w.cc:55
@ MINUS
Definition: chromabase.h:45
@ PLUS
Definition: chromabase.h:45
multi1d< LatticeFermion > chi(Ncb)
LatticeFermion psi
Definition: mespbg5p_w.cc:35
DComplex d
Definition: invbicg.cc:99
START_CODE()
A(A, psi, r, Ncb, PLUS)
Double zero
Definition: invbicg.cc:106
multi1d< LatticeFermion > s(Ncb)
@ RECONS_12
Definition: enum_quda_io.h:80
@ RECONS_NONE
Definition: enum_quda_io.h:78
@ RECONS_8
Definition: enum_quda_io.h:79
FloatingPoint< double > Double
Definition: gtest.h:7351
::std::string string
Definition: gtest.h:1979
Double r_norm
Definition: pade_trln_w.cc:86
Periodic ferm state and a creator.
#define FORWARD
Definition: primitives.h:82
Reunitarize in place a color matrix to SU(N)
Simple fermionic BC.
Support class for fermion actions and linear operators.
Linear system solvers.
multi1d< LatticeColorMatrix > U
multi1d< LatticeColorMatrix > Q
Definition: t_clover.cc:12
multi1d< LatticeColorMatrixF > QF
Definition: t_quda_tprec.cc:19
LatticeColorMatrixF UF
Definition: t_quda_tprec.cc:18
LatticeFermionD TD
Definition: t_quda_tprec.cc:22
LatticeColorMatrixD UD
Definition: t_quda_tprec.cc:23
LatticeFermionF TF
Definition: t_quda_tprec.cc:17
multi1d< LatticeColorMatrixD > QD
Definition: t_quda_tprec.cc:24
Axial gauge fixing.