CHROMA
syssolver_mdagm_clover_qphix_w.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! \file
3  * \brief Solve a M*psi=chi linear system by BiCGStab
4  */
5 
6 #ifndef __syssolver_mdagm_clover_qphix_h__
7 #define __syssolver_mdagm_clover_qphix_h__
8 
9 #include "chroma_config.h"
10 
11 #ifdef BUILD_QPHIX
12 #include "handle.h"
13 #include "state.h"
14 #include "syssolver.h"
15 #include "linearop.h"
16 #include "lmdagm.h"
24 #include "io/aniso_io.h"
25 #include <string>
26 
27 #include "chroma_config.h"
28 #include "util/gauge/reunit.h"
29 #include "io/aniso_io.h"
30 
31 // Header files from the dslash package
32 #include "qphix/geometry.h"
33 #include "qphix/qdp_packer.h"
34 #include "qphix/clover.h"
35 #include "qphix/invcg.h"
36 #include "qphix/invbicgstab.h"
37 
38 #include "qphix_singleton.h"
40 #include "qphix/blas_new_c.h"
41 using namespace QDP;
42 
43 namespace Chroma
44 {
45 
46  //! Richardson system solver namespace
47  namespace MdagMSysSolverQPhiXCloverEnv
48  {
49  //! Register the syssolver
50  bool registerAll();
51 
52  }
53 
54 
55  //! Solve a Clover Fermion System using the QPhiX inverter
56  /*! \ingroup invert
57  *** WARNING THIS SOLVER WORKS FOR Clover FERMIONS ONLY ***
58  */
59  using namespace QPhiXVecTraits;
60 
61  template<typename T, typename U>
62  class MdagMSysSolverQPhiXClover : public MdagMSystemSolver<T>
63  {
64  public:
65  typedef multi1d<U> Q;
66  typedef typename WordType<T>::Type_t REALT;
67  typedef typename QPhiX::Geometry<REALT,VecTraits<REALT>::Vec,VecTraits<REALT>::Soa,VecTraits<REALT>::compress12>::FourSpinorBlock QPhiX_Spinor;
68  typedef typename QPhiX::Geometry<REALT,VecTraits<REALT>::Vec,VecTraits<REALT>::Soa,VecTraits<REALT>::compress12>::SU3MatrixBlock QPhiX_Gauge;
69  typedef typename QPhiX::Geometry<REALT,VecTraits<REALT>::Vec,VecTraits<REALT>::Soa,VecTraits<REALT>::compress12>::CloverBlock QPhiX_Clover;
70 
71 
72  //! Constructor
73  /*!
74  * \param M_ Linear operator ( Read )
75  * \param invParam inverter parameters ( Read )
76  */
77  MdagMSysSolverQPhiXClover(Handle< LinearOperator<T> > A_,
78  Handle< FermState<T,Q,Q> > state_,
79  const SysSolverQPhiXCloverParams& invParam_) :
80  A(A_), invParam(invParam_), clov(new CloverTermT<T, U>()), invclov(new CloverTermT<T, U>())
81  {
82  QDPIO::cout << "MdagMSysSolverQPhiXClover:" << std::endl;
83  QDPIO::cout << "AntiPeriodicT is: " << invParam.AntiPeriodicT << std::endl;
84 
85 
86  QDPIO::cout << "Veclen is " << VecTraits<REALT>::Vec << std::endl;
87  QDPIO::cout << "Soalen is " << VecTraits<REALT>::Soa << std::endl;
88  if ( VecTraits<REALT>::Soa > VecTraits<REALT>::Vec ) {
89  QDPIO::cerr << "PROBLEM: Soalen > Veclen. Please set soalen appropriately (<=VECLEN) at compile time" << std::endl;
90  QDP_abort(1);
91  }
92 
93  Q u(Nd);
94  for(int mu=0; mu < Nd; mu++) {
95  u[mu] = state_->getLinks()[mu];
96  }
97 
98  // Set up aniso coefficients
99  multi1d<Real> aniso_coeffs(Nd);
100  for(int mu=0; mu < Nd; mu++) aniso_coeffs[mu] = Real(1);
101 
102  bool anisotropy = invParam.CloverParams.anisoParam.anisoP;
103  if( anisotropy ) {
104  aniso_coeffs = makeFermCoeffs( invParam.CloverParams.anisoParam );
105  }
106 
107  double t_boundary=(double)(1);
108  // NB: In this case, the state will have boundaries applied.
109  // So we only need to apply our own boundaries if Compression is enabled
110  //
111  if (invParam.AntiPeriodicT) {
112  t_boundary=(double)(-1);
113  // Flip off the boundaries -- Dslash expects them off..
114  u[3] *= where(Layout::latticeCoordinate(3) == (Layout::lattSize()[3]-1),
115  Real(t_boundary), Real(1));
116  }
117 
118  cbsize_in_blocks = rb[0].numSiteTable()/VecTraits<REALT>::Soa;
119 
120  const QPhiX::QPhiXCLIArgs& QPhiXParams = TheQPhiXParams::Instance();
121 
122 #ifdef QDP_IS_QDPJIT
123  int pad_xy=0;
124  int pad_xyz=0;
125 #else
126  int pad_xy = QPhiXParams.getPxy();
127  int pad_xyz= QPhiXParams.getPxyz();
128 #endif
129  n_blas_simt = QPhiXParams.getSy()*QPhiXParams.getSz();
130 
131  QDPIO::cout << "About to grap a Dslash" << std::endl;
132  geom = new QPhiX::Geometry<REALT, VecTraits<REALT>::Vec, VecTraits<REALT>::Soa,VecTraits<REALT>::compress12>(Layout::subgridLattSize().slice(),
133  QPhiXParams.getBy(),
134  QPhiXParams.getBz(),
135  QPhiXParams.getNCores(),
136  QPhiXParams.getSy(),
137  QPhiXParams.getSz(),
138  pad_xy,
139  pad_xyz,
140  QPhiXParams.getMinCt());
141 
142  QDPIO::cout << " Allocating p and c" << std::endl << std::flush ;
143 
144 #ifndef QPD_IS_QDPJIT
145  psi_qphix=(QPhiX_Spinor *)geom->allocCBFourSpinor();
146  chi_qphix=(QPhiX_Spinor *)geom->allocCBFourSpinor();
147 
148  if( invParam.SolverType == BICGSTAB ) {
149  // Two step solve need a temporary
150  tmp_qphix=(QPhiX_Spinor *)geom->allocCBFourSpinor();
151  }
152 #else
153  psi_qphix = nullptr;
154  chi_qphix = nullptr;
155  tmp_qphix = nullptr;
156 
157 #endif
158 
159 
160  QDPIO::cout << " Allocating Clover" << std::endl << std::flush ;
161  QPhiX_Clover* A_cb0=(QPhiX_Clover *)geom->allocCBClov();
162  QPhiX_Clover* A_cb1=(QPhiX_Clover *)geom->allocCBClov();
163  clov_packed[0] = A_cb0;
164  clov_packed[1] = A_cb1;
165 
166  QDPIO::cout << " Allocating CloverInv " << std::endl << std::flush ;
167  QPhiX_Clover* A_inv_cb0=(QPhiX_Clover *)geom->allocCBClov();
168  QPhiX_Clover* A_inv_cb1=(QPhiX_Clover *)geom->allocCBClov();
169  invclov_packed[0] = A_inv_cb0;
170  invclov_packed[1] = A_inv_cb1;
171 
172  // Pack the gauge field
173  QDPIO::cout << "Packing gauge field..." << std::endl << std::flush ;
174  QPhiX_Gauge* packed_gauge_cb0=(QPhiX_Gauge *)geom->allocCBGauge();
175  QPhiX_Gauge* packed_gauge_cb1=(QPhiX_Gauge *)geom->allocCBGauge();
176 
177  QPhiX::qdp_pack_gauge<>(u, packed_gauge_cb0,packed_gauge_cb1, *geom);
178  u_packed[0] = packed_gauge_cb0;
179  u_packed[1] = packed_gauge_cb1;
180 
181 
182  QDPIO::cout << "Creating Clover Term" << std::endl;
183  CloverTerm clov_qdp;
184  clov->create(state_, invParam.CloverParams);
185  QDPIO::cout << "Inverting Clover Term" << std::endl;
186  invclov->create(state_, invParam.CloverParams, (*clov));
187  for(int cb=0; cb < 2; cb++) {
188  invclov->choles(cb);
189  }
190  QDPIO::cout << "Done" << std::endl;
191  QDPIO::cout << "Packing Clover term..." << std::endl;
192 
193  for(int cb=0; cb < 2; cb++) {
194  QPhiX::qdp_pack_clover<>((*invclov), invclov_packed[cb], *geom, cb);
195  }
196 
197  for(int cb=0; cb < 2; cb++) {
198  QPhiX::qdp_pack_clover<>((*clov), clov_packed[cb], *geom, cb);
199  }
200  QDPIO::cout << "Done" << std::endl;
201 
202  QDPIO::cout << "Creating the Even Odd Operator" << std::endl;
203  M=new QPhiX::EvenOddCloverOperator<REALT,VecTraits<REALT>::Vec,VecTraits<REALT>::Soa,VecTraits<REALT>::compress12>(u_packed,
204  clov_packed[1],
205  invclov_packed[0],
206  geom,
207  t_boundary,
208  toDouble(aniso_coeffs[0]),
209  toDouble(aniso_coeffs[3]));
210 
211 
212  switch( invParam.SolverType ) {
213  case CG:
214  {
215  QDPIO::cout << "Creating the CG Solver" << std::endl;
216  cg_solver = new QPhiX::InvCG<REALT,VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12>((*M), invParam.MaxIter);
217  }
218  case BICGSTAB:
219  {
220  QDPIO::cout << "Creating the BiCGStab Solver" << std::endl;
221  bicgstab_solver = new QPhiX::InvBiCGStab<REALT,VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12>((*M), invParam.MaxIter);
222  }
223  break;
224  default:
225  QDPIO::cerr << "UNKNOWN Solver Type" << std::endl;
226  QDP_abort(1);
227  }
228  }
229 
230 
231 
232  //! Destructor is automatic
233  ~MdagMSysSolverQPhiXClover()
234  {
235 
236  // Need to unalloc all the memory...
237  QDPIO::cout << "Destructing" << std::endl;
238 
239 #ifndef QDP_IS_QDPJIT
240  geom->free(psi_qphix);
241  geom->free(chi_qphix);
242  if( invParam.SolverType == BICGSTAB ) {
243  geom->free(tmp_qphix);
244  }
245 
246 #endif
247  psi_qphix = nullptr;
248  chi_qphix = nullptr;
249  tmp_qphix = nullptr;
250 
251  geom->free(invclov_packed[0]);
252  geom->free(invclov_packed[1]);
253  invclov_packed[0] = nullptr;
254  invclov_packed[1] = nullptr;
255 
256  geom->free(clov_packed[0]);
257  geom->free(clov_packed[1]);
258  clov_packed[0] = nullptr;
259  clov_packed[1] = nullptr;
260 
261  geom->free(u_packed[0]);
262  geom->free(u_packed[1]);
263  u_packed[0] = nullptr;
264  u_packed[1] = nullptr;
265 
266  delete geom;
267 
268  // Evertyhing else freed as handles freed.
269  }
270 
271  //! Return the subset on which the operator acts
272  const Subset& subset() const {return A->subset();}
273 
274 
275  SystemSolverResults_t operator()(T& psi, const T& chi,
276  Chroma::AbsChronologicalPredictor4D<T>& predictor) const
277  {
278 
279  START_CODE();
280  StopWatch swatch;
281  swatch.reset(); swatch.start();
282  /* Factories here later? */
283  SystemSolverResults_t res;
284  switch( invParam.SolverType ) {
285  case CG:
286  {
287  res = cgSolve(psi,chi,predictor);
288  }
289  break;
290  case BICGSTAB:
291  {
292  res = biCGStabSolve(psi,chi,predictor);
293  }
294  break;
295  default:
296  QDPIO::cout << "Unknown Solver " << std::endl;
297  break;
298  }
299 
300  swatch.stop();
301  QDPIO::cout << "QPHIX_MDAGM_SOLVER: total time: " << swatch.getTimeInSeconds() << " (sec)" << std::endl;
302  END_CODE();
303  return res;
304  }
305 
306 
307  //! Solver the linear system
308  /*!
309  * \param psi solution ( Modify )
310  * \param chi source ( Read )
311  * \return syssolver results
312  */
313 
314  // NEED THE CHRONO Predictor argument here...
315  SystemSolverResults_t operator()(T& psi, const T& chi) const
316  {
317  START_CODE();
318  SystemSolverResults_t res;
319  Null4DChronoPredictor not_predicting;
320  res=(*this)(psi,chi, not_predicting);
321 
322  END_CODE();
323  return res;
324  }
325 
326 
327 
328 
329 
330  private:
331  // Hide default constructor
332  MdagMSysSolverQPhiXClover() {}
333 
334 
335 
336  Handle< LinearOperator<T> > A;
337  const SysSolverQPhiXCloverParams invParam;
338  Handle< CloverTermT<T, U> > clov;
339  Handle< CloverTermT<T, U> > invclov;
340 
341  QPhiX::Geometry<REALT, VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12>* geom;
342 
343  Handle< QPhiX::EvenOddCloverOperator<REALT, VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12> > M;
344 
345  Handle< QPhiX::InvCG<REALT,VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12> > cg_solver;
346 
347  Handle< QPhiX::InvBiCGStab<REALT,VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12> > bicgstab_solver;
348 
349  QPhiX_Clover* invclov_packed[2];
350  QPhiX_Clover* clov_packed[2];
351  QPhiX_Gauge* u_packed[2];
352 
353  mutable QPhiX_Spinor* psi_qphix;
354  mutable QPhiX_Spinor* chi_qphix;
355  mutable QPhiX_Spinor* tmp_qphix;
356 
357  size_t cbsize_in_blocks;
358  int n_blas_simt;
359 
360  SystemSolverResults_t cgSolve(T& psi, const T& chi, AbsChronologicalPredictor4D<T>& predictor) const
361  {
362  SystemSolverResults_t res;
363  Handle< LinearOperator<T> > MdagM( new MdagMLinOp<T>(A) );
364  predictor(psi, (*MdagM), chi);
365 
366 #ifndef QDP_IS_QDPJIT
367  // Pack Spinors psi and chi
368  QPhiX::qdp_pack_cb_spinor<>(psi, psi_qphix, *geom,1);
369  QPhiX::qdp_pack_cb_spinor<>(chi, chi_qphix, *geom,1);
370 #else
371  psi_qphix = (QPhiX_Spinor*)(psi.getFjit()) + cbsize_in_blocks;
372  chi_qphix = (QPhiX_Spinor*)(chi.getFjit()) + cbsize_in_blocks;
373 #endif
374  double rsd_final;
375  unsigned long site_flops=0;
376  unsigned long mv_apps=0;
377 
378  double start = omp_get_wtime();
379  int my_isign=1;
380  (*cg_solver)(psi_qphix, chi_qphix, toDouble(invParam.RsdTarget), res.n_count, rsd_final, site_flops, mv_apps, my_isign, invParam.VerboseP);
381  double end = omp_get_wtime();
382 
383 #ifndef QDP_IS_QDPJIT
384  QPhiX::qdp_unpack_cb_spinor<>(psi_qphix, psi, *geom,1);
385 #endif
386 
387  predictor.newVector(psi);
388 
389  // Chi Should now hold the result spinor
390  // Check it against chroma.
391  {
392  T r = chi;
393  T tmp,tmp2;
394  (*A)(tmp, psi, PLUS);
395  (*A)(tmp2, tmp, MINUS);
396  r[ A->subset() ] -= tmp2;
397 
398  Double r2 = norm2(r,A->subset());
399  Double b2 = norm2(chi, A->subset());
400  Double rel_resid = sqrt(r2/b2);
401  res.resid = rel_resid;
402  QDPIO::cout << "QPHIX_CLOVER_CG_SOLVER: " << res.n_count << " iters, rsd_sq_final=" << rel_resid << std::endl;
403 
404  QDPIO::cout << "QPHIX_CLOVER_CG_SOLVER: || r || / || b || = " << rel_resid << std::endl;
405 
406 #if 0
407  if ( !toBool ( rel_resid < invParam.RsdTarget*invParam.RsdToleranceFactor ) ) {
408  QDPIO::cout << "SOLVE FAILED" << std::endl;
409  QDP_abort(1);
410  }
411 #endif
412  }
413 
414  int num_cb_sites = Layout::vol()/2;
415  unsigned long total_flops = (site_flops + (1320+504+1320+504+48)*mv_apps)*num_cb_sites;
416  double gflops = (double)(total_flops)/(1.0e9);
417 
418  double total_time = end - start;
419  QDPIO::cout << "QPHIX_CLOVER_CG_SOLVER: Solver Time="<< total_time <<" (sec) Performance=" << gflops / total_time << " GFLOPS" << std::endl;
420 
421  END_CODE();
422  return res;
423 
424  }
425 
426 
427  SystemSolverResults_t biCGStabSolve(T& psi, const T& chi,AbsChronologicalPredictor4D<T>& predictor) const
428  {
429  START_CODE();
430  StopWatch swatch;
431  swatch.reset(); swatch.start();
432 
433  SystemSolverResults_t res;
434  Handle< LinearOperator<T> > MdagM( new MdagMLinOp<T>(A) );
435 
436  T Y;
437  Y[ A->subset() ] = psi; // Y is initial guess
438 
439  try {
440  // Try to cast the predictor to a two step predictor
441  AbsTwoStepChronologicalPredictor4D<T>& two_step_predictor =
442  dynamic_cast<AbsTwoStepChronologicalPredictor4D<T>& >(predictor);
443 
444 
445  // Predict Y and X separately
446  two_step_predictor.predictY(Y,*A,chi);
447  two_step_predictor.predictX(psi,*MdagM, chi);
448  }
449  catch( std::bad_cast) {
450 
451  // Not a 2 step predictor. Predict X
452  // Then MX = Y is a good guess.
453  predictor(psi,*MdagM, chi);
454  (*A)(Y,psi,PLUS);
455 
456  }
457 
458 
459 #ifndef QDP_IS_QDPJIT
460  QDPIO::cout << "Packing" << std::endl << std::flush ;
461  QPhiX::qdp_pack_cb_spinor<>(Y, tmp_qphix, *geom,1); // Initial Guess for Y
462  QPhiX::qdp_pack_cb_spinor<>(psi, psi_qphix, *geom,1); // Initial Guess for X
463  QPhiX::qdp_pack_cb_spinor<>(chi, chi_qphix, *geom,1); // RHS
464 #else
465  tmp_qphix = (QPhiX_Spinor *)(Y.getFjit()) + cbsize_in_blocks;
466  psi_qphix = (QPhiX_Spinor *)(psi.getFjit()) + cbsize_in_blocks;
467  chi_qphix = (QPhiX_Spinor *)(chi.getFjit()) + cbsize_in_blocks;
468 #endif
469  QDPIO::cout << "Done" << std::endl << std::flush;
470  double rsd_final;
471  int num_cb_sites = Layout::vol()/2;
472 
473  unsigned long site_flops1=0;
474  unsigned long mv_apps1=0;
475  int n_count1=0;
476 
477  unsigned long site_flops2=0;
478  unsigned long mv_apps2=0;
479  int n_count2=0;
480 
481  QDPIO::cout << "Starting Y solve" << std::endl << std::flush ;
482  double start = omp_get_wtime();
483  (*bicgstab_solver)(tmp_qphix,chi_qphix, toDouble(invParam.RsdTarget), n_count1, rsd_final, site_flops1, mv_apps1, -1, invParam.VerboseP);
484  double end = omp_get_wtime();
485 
486 
487  unsigned long total_flops = (site_flops1 + (1320+504+1320+504+48)*mv_apps1)*num_cb_sites;
488  double gflops = (double)(total_flops)/(1.0e9);
489  double total_time = end - start;
490 
491  Double r_final = sqrt(toDouble(rsd_final)/norm2(chi,A->subset()));
492  QDPIO::cout << "QPHIX_CLOVER_BICGSTAB_SOLVER: " << n_count1 << " iters, rsd_sq_final=" << rsd_final << " ||r||/||b|| (acc) = " << r_final <<std::endl;
493  QDPIO::cout << "QPHIX_CLOVER_BICGSTAB_SOLVER: Solver Time="<< total_time <<" (sec) Performance=" << gflops / total_time << " GFLOPS" << std::endl;
494 
495  QDPIO::cout << "Starting X solve" << std::endl << std::flush ;
496  start = omp_get_wtime();
497  (*bicgstab_solver)(psi_qphix,tmp_qphix, toDouble(invParam.RsdTarget), n_count2, rsd_final, site_flops2, mv_apps2, +1, invParam.VerboseP);
498  end = omp_get_wtime();
499  total_flops = (site_flops2 + (1320+504+1320+504+48)*mv_apps2)*num_cb_sites;
500  gflops = (double)(total_flops)/(1.0e9);
501  total_time = end - start;
502 
503 #ifndef QDP_IS_QDPJIT
504  // Want Norm of Y
505  QPhiX::qdp_unpack_cb_spinor<>(tmp_qphix, Y, *geom,1);
506 #endif
507  double norm2Y;
508  QPhiX::norm2Spinor(norm2Y, tmp_qphix, *geom, n_blas_simt);
509  r_final = sqrt(toDouble(rsd_final)/norm2Y);
510 
511  QDPIO::cout << "QPHIX_CLOVER_BICGSTAB_SOLVER: " << n_count2 << " iters, rsd_sq_final=" << rsd_final << " ||r||/||b|| (acc) = " << r_final << std::endl;
512  QDPIO::cout << "QPHIX_CLOVER_BICGSTAB_SOLVER: Solver Time="<< total_time <<" (sec) Performance=" << gflops / total_time << " GFLOPS" << std::endl;
513 
514 #ifndef QDP_IS_QDPJIT
515  QPhiX::qdp_unpack_cb_spinor<>(psi_qphix, psi, *geom,1);
516 #endif
517 
518  try {
519  // Try to cast the predictor to a two step predictor
520  AbsTwoStepChronologicalPredictor4D<T>& two_step_predictor =
521  dynamic_cast<AbsTwoStepChronologicalPredictor4D<T>& >(predictor);
522  two_step_predictor.newYVector(Y);
523  two_step_predictor.newXVector(psi);
524 
525  }
526  catch( std::bad_cast) {
527 
528  // Not a 2 step predictor. Predict X
529  // Then MX = Y is a good guess.
530  predictor.newVector(psi);
531  }
532 
533  // Chi Should now hold the result spinor
534  // Check it against chroma. -- reuse Y as the residuum
535  Y[ A->subset() ] = chi;
536  {
537  T tmp,tmp2;
538  (*A)(tmp, psi, PLUS);
539  (*A)(tmp2, tmp, MINUS);
540 
541  Y[ A->subset() ] -= tmp2;
542  }
543 
544  Double r2 = norm2(Y,A->subset());
545  Double b2 = norm2(chi, A->subset());
546  Double rel_resid = sqrt(r2/b2);
547  res.resid=rel_resid;
548  res.n_count = n_count1 + n_count2;
549  QDPIO::cout << "QPHIX_CLOVER_BICGSTAB_SOLVER: total_iters="<<res.n_count<<" || r || / || b || = " << res.resid << std::endl;
550 
551 
552 #if 0
553  if ( !toBool ( rel_resid < invParam.RsdTarget*invParam.RsdToleranceFactor ) ) {
554  QDPIO::cout << "SOLVE FAILED" << std::endl;
555  QDP_abort(1);
556  }
557 #endif
558 
559  swatch.stop();
560  QDPIO::cout << "QPHIX_MDAGM_SOLVER: total time: " << swatch.getTimeInSeconds() << " (sec)" << std::endl;
561  END_CODE();
562  return res;
563  }
564 
565  };
566 
567 
568 } // End namespace
569 
570 #endif // BUILD_QPHIX
571 #endif
572 
Anisotropy parameters.
#define END_CODE()
Definition: chromabase.h:65
#define START_CODE()
Definition: chromabase.h:64
Abstract interface for a Chronological Solution predictor.
void create(Handle< FermState< T, multi1d< U >, multi1d< U > > > fs, const CloverFermActParams &param_)
Creation routine.
Include possibly optimized Clover terms.
int mu
Definition: cool.cc:24
Even-odd preconditioned Clover fermion linear operator.
Class for counted reference semantics.
Linear Operators.
M^dag*M composition of a linear operator.
Double tmp
Definition: meslate.cc:60
Nd
Definition: meslate.cc:74
Double tmp2
Definition: mesq.cc:30
bool registerAll()
Register all the factories.
multi1d< Hadron2PtContraction_t > operator()(const multi1d< LatticeColorMatrix > &u)
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
static multi1d< LatticeColorMatrix > u
LinOpSysSolverMGProtoClover::Q Q
QDPCloverTerm CloverTerm
Definition: clover_term_w.h:92
@ MINUS
Definition: chromabase.h:45
@ PLUS
Definition: chromabase.h:45
QDPCloverTermT< T, U > CloverTermT
Definition: clover_term_w.h:97
A(A, psi, r, Ncb, PLUS)
int cb
Definition: invbicg.cc:120
multi1d< Real > makeFermCoeffs(const AnisoParam_t &aniso)
Make fermion coefficients.
Definition: aniso_io.cc:63
FloatingPoint< double > Double
Definition: gtest.h:7351
Null predictor: Leaves input x0 unchanged.
multi1d< LatticeFermion > r(Ncb)
chi
Definition: pade_trln_w.cc:24
psi
Definition: pade_trln_w.cc:191
Periodic ferm state and a creator.
Fermion action factories.
Reunitarize in place a color matrix to SU(N)
Simple fermionic BC.
Support class for fermion actions and linear operators.
Linear system solvers.
Handle< LinearOperator< T > > MdagM
multi1d< LatticeColorMatrix > U
LatticeFermion T
Definition: t_clover.cc:11
multi1d< LatticeColorMatrix > Q
Definition: t_clover.cc:12
Axial gauge fixing.