6 #ifndef __multi_syssolver_mdagm_cg_wilson_quda_w_h__
7 #define __multi_syssolver_mdagm_cg_wilson_quda_w_h__
32 namespace MdagMMultiSysSolverCGQudaWilsonEnv
41 class MdagMMultiSysSolverCGQudaWilson :
public MdagMMultiSystemSolver<LatticeFermion>
44 typedef LatticeFermion
T;
45 typedef LatticeColorMatrix
U;
46 typedef multi1d<LatticeColorMatrix>
Q;
47 typedef multi1d<LatticeColorMatrix>
P;
49 typedef LatticeFermionF
TF;
50 typedef LatticeColorMatrixF
UF;
51 typedef multi1d<LatticeColorMatrixF>
QF;
52 typedef multi1d<LatticeColorMatrixF>
PF;
54 typedef LatticeFermionD
TD;
55 typedef LatticeColorMatrixD
UD;
56 typedef multi1d<LatticeColorMatrixD>
QD;
57 typedef multi1d<LatticeColorMatrixD>
PD;
59 typedef WordType<T>::Type_t REALT;
65 MdagMMultiSysSolverCGQudaWilson(Handle< LinearOperator<T> > M_,
66 Handle< FermState<T,P,Q> > state_,
67 const SysSolverQUDAWilsonParams& invParam_) :
68 A(M_), invParam(invParam_)
71 QDPIO::cout <<
"MdagMMultiSysSolverCGQUDAWilson: " << std::endl;
75 int s =
sizeof( WordType<T>::Type_t );
77 cpu_prec = QUDA_SINGLE_PRECISION;
80 cpu_prec = QUDA_DOUBLE_PRECISION;
85 switch( invParam.cudaPrecision ) {
87 gpu_prec = QUDA_HALF_PRECISION;
90 gpu_prec = QUDA_SINGLE_PRECISION;
93 gpu_prec = QUDA_DOUBLE_PRECISION;
100 gpu_half_prec = gpu_prec;
104 QDPIO::cout <<
" Calling new QUDA Invert Param" << std::endl;
105 q_gauge_param = newQudaGaugeParam();
106 quda_inv_param = newQudaInvertParam();
109 const multi1d<int>& latdims = Layout::subgridLattSize();
111 q_gauge_param.X[0] = latdims[0];
112 q_gauge_param.X[1] = latdims[1];
113 q_gauge_param.X[2] = latdims[2];
114 q_gauge_param.X[3] = latdims[3];
119 q_gauge_param.type = QUDA_WILSON_LINKS;
120 q_gauge_param.gauge_order = QUDA_QDP_GAUGE_ORDER;
126 if( invParam.AntiPeriodicT ) {
127 q_gauge_param.t_boundary = QUDA_ANTI_PERIODIC_T;
130 q_gauge_param.t_boundary = QUDA_PERIODIC_T;
134 q_gauge_param.cpu_prec = cpu_prec;
135 q_gauge_param.cuda_prec = gpu_prec;
138 switch( invParam.cudaReconstruct ) {
140 q_gauge_param.reconstruct = QUDA_RECONSTRUCT_NO;
143 q_gauge_param.reconstruct = QUDA_RECONSTRUCT_8;
146 q_gauge_param.reconstruct = QUDA_RECONSTRUCT_12;
149 q_gauge_param.reconstruct = QUDA_RECONSTRUCT_12;
153 q_gauge_param.cuda_prec_sloppy = gpu_half_prec;
155 switch( invParam.cudaSloppyReconstruct ) {
157 q_gauge_param.reconstruct_sloppy = QUDA_RECONSTRUCT_NO;
160 q_gauge_param.reconstruct_sloppy = QUDA_RECONSTRUCT_8;
163 q_gauge_param.reconstruct_sloppy = QUDA_RECONSTRUCT_12;
166 q_gauge_param.reconstruct_sloppy = QUDA_RECONSTRUCT_12;
178 links_single[
mu] = (state_->getLinks())[
mu];
182 if( invParam.axialGaugeP ) {
183 QDPIO::cout <<
"Fixing Temporal Gauge" << std::endl;
186 links_single[
mu] = GFixMat*(state_->getLinks())[
mu]*adj(shift(GFixMat,
FORWARD,
mu));
188 q_gauge_param.gauge_fix = QUDA_GAUGE_FIXED_YES;
192 q_gauge_param.gauge_fix = QUDA_GAUGE_FIXED_NO;
196 const AnisoParam_t& aniso = invParam.WilsonParams.anisoParam;
198 Real gamma_f = aniso.xi_0 / aniso.nu;
199 q_gauge_param.anisotropy = toDouble(gamma_f);
202 q_gauge_param.anisotropy = 1.0;
207 Handle<FermState<T,Q,Q> > fstate(
new PeriodicFermState<T,Q,Q>(links_single));
212 links_single[
mu] *= cf[
mu];
218 quda_inv_param.dslash_type = QUDA_WILSON_DSLASH;
219 solver_string =
"MULTI_CG";
220 quda_inv_param.inv_type = QUDA_CG_INVERTER;
223 Real massParam = Real(1) + Real(3)/Real(q_gauge_param.anisotropy) + invParam.WilsonParams.Mass;
224 quda_inv_param.kappa = 1.0/(2*toDouble(massParam));
230 quda_inv_param.clover_coeff = 1.0;
232 quda_inv_param.mass_normalization = QUDA_ASYMMETRIC_MASS_NORMALIZATION;
234 quda_inv_param.tol = toDouble(invParam.RsdTarget);
235 quda_inv_param.maxiter = invParam.MaxIter;
236 quda_inv_param.reliable_delta = toDouble(invParam.Delta);
237 quda_inv_param.pipeline = invParam.Pipeline;
240 quda_inv_param.solution_type = QUDA_MATPCDAG_MATPC_SOLUTION;
243 switch( invParam.solverType ) {
245 quda_inv_param.solve_type = QUDA_NORMOP_PC_SOLVE;
248 QDPIO::cerr <<
"Only CG Is currently implemented for multi-shift" << std::endl;
254 if( invParam.asymmetricP ) {
255 QDPIO::cout <<
"Asymmetric LinOP" << std::endl;
256 quda_inv_param.matpc_type = QUDA_MATPC_ODD_ODD_ASYMMETRIC;
259 QDPIO::cout <<
"Symmetric LinOp" << std::endl;
260 quda_inv_param.matpc_type = QUDA_MATPC_ODD_ODD;
263 quda_inv_param.dagger = QUDA_DAG_NO;
266 quda_inv_param.cpu_prec = cpu_prec;
267 quda_inv_param.cuda_prec = gpu_prec;
268 quda_inv_param.cuda_prec_sloppy = gpu_half_prec;
269 quda_inv_param.preserve_source = QUDA_PRESERVE_SOURCE_YES;
270 quda_inv_param.dirac_order = QUDA_DIRAC_ORDER;
271 quda_inv_param.gamma_basis = QUDA_DEGRAND_ROSSI_GAMMA_BASIS;
274 if( invParam.tuneDslashP ) {
275 QDPIO::cout <<
"Enabling Dslash Autotuning" << std::endl;
277 quda_inv_param.tune = QUDA_TUNE_YES;
280 QDPIO::cout <<
"Disabling Dslash Autotuning" << std::endl;
282 quda_inv_param.tune = QUDA_TUNE_NO;
288 multi1d<int> face_size(4);
289 face_size[0] = latdims[1]*latdims[2]*latdims[3]/2;
290 face_size[1] = latdims[0]*latdims[2]*latdims[3]/2;
291 face_size[2] = latdims[0]*latdims[1]*latdims[3]/2;
292 face_size[3] = latdims[0]*latdims[1]*latdims[2]/2;
294 int max_face = face_size[0];
295 for(
int i=1;
i <=3;
i++) {
296 if ( face_size[
i] > max_face ) {
297 max_face = face_size[
i];
302 q_gauge_param.ga_pad = max_face;
303 quda_inv_param.sp_pad = 0;
304 quda_inv_param.cl_pad = 0;
310 QDPIO::cout <<
"Setting Precondition stuff to defaults for not using" << std::endl;
311 quda_inv_param.inv_type_precondition= QUDA_INVALID_INVERTER;
312 quda_inv_param.tol_precondition = 1.0e-1;
313 quda_inv_param.maxiter_precondition = 1000;
314 quda_inv_param.verbosity_precondition = QUDA_SILENT;
315 quda_inv_param.gcrNkrylov = 1;
317 if( invParam.verboseP ) {
318 quda_inv_param.verbosity = QUDA_VERBOSE;
321 quda_inv_param.verbosity = QUDA_SUMMARIZE;
328 gauge[
mu] = (
void *)&(links_single[
mu].elem(all.start()).elem().elem(0,0).real());
332 loadGaugeQuda((
void *)gauge, &q_gauge_param);
337 ~MdagMMultiSysSolverCGQudaWilson() {
338 QDPIO::cout <<
"Destructing" << std::endl;
343 const Subset& subset()
const {
return A->subset();}
351 SystemSolverResults_t
operator() (multi1d<T>&
psi,
const multi1d<Real>& shifts,
const T&
chi)
const
357 SystemSolverResults_t res;
360 if ( invParam.axialGaugeP ) {
362 multi1d<T> g_psi(
psi.size());
365 QDPIO::cout <<
"Gauge Fixing source and initial guess" << std::endl;
366 g_chi[ rb[1] ] = GFixMat *
chi;
367 for(
int s=0;
s <
psi.size();
s++) {
368 g_psi[
s][ rb[1] ] =
zero;
371 QDPIO::cout <<
"Solving" << std::endl;
372 res = qudaInvertMulti(
376 QDPIO::cout <<
"Untransforming solution." << std::endl;
377 for(
int s=0;
s<
psi.size();
s++) {
378 psi[
s][ rb[1]] = adj(GFixMat)*g_psi[
s];
384 res = qudaInvertMulti(
chi,
391 double time = swatch.getTimeInSeconds();
393 if (invParam.verboseP ) {
395 multi1d<Double> r_rel(shifts.size());
397 for(
int i=0;
i < shifts.size();
i++) {
409 r_rel[
i] = sqrt(norm2(
r,
A->subset())/chinorm );
410 QDPIO::cout <<
"r[" <<
i <<
"] = " << r_rel[
i] << std::endl;
413 QDPIO::cout <<
"MULTI_CG_QUDA_CLOVER_SOLVER: " << res.n_count <<
" iterations. Rsd = " << res.resid << std::endl;
414 QDPIO::cout <<
"MULTI_CG_QUDA_CLOVER_SOLVER: "<<time<<
" sec" << std::endl;
423 MdagMMultiSysSolverCGQudaWilson() {}
425 QudaPrecision_s cpu_prec;
426 QudaPrecision_s gpu_prec;
427 QudaPrecision_s gpu_half_prec;
429 Handle< LinearOperator<T> >
A;
430 const SysSolverQUDAWilsonParams invParam;
431 QudaGaugeParam q_gauge_param;
432 mutable QudaInvertParam quda_inv_param;
434 SystemSolverResults_t qudaInvertMulti(
const T& chi_s,
void temporalGauge(multi1d< LatticeColorMatrix > &ug, LatticeColorMatrix &g, int decay_dir)
Temporal gauge fixing.
Class for counted reference semantics.
M^dag*M composition of a linear operator.
multi1d< LatticeColorMatrix > P
bool registerAll()
Register all the factories.
multi1d< Hadron2PtContraction_t > operator()(const multi1d< LatticeColorMatrix > &u)
Asqtad Staggered-Dirac operator.
LinOpSysSolverMGProtoClover::Q Q
LinOpSysSolverMGProtoClover::T T
multi1d< LatticeFermion > chi(Ncb)
multi1d< Real > makeFermCoeffs(const AnisoParam_t &aniso)
Make fermion coefficients.
multi1d< LatticeFermion > s(Ncb)
FloatingPoint< double > Double
Periodic ferm state and a creator.
Reunitarize in place a color matrix to SU(N)
multi1d< LatticeColorMatrix > U
multi1d< LatticeColorMatrix > Q
multi1d< LatticeColorMatrixF > QF
multi1d< LatticeColorMatrixF > PF
multi1d< LatticeColorMatrixD > PD
multi1d< LatticeColorMatrixD > QD