6 #ifndef __syssolver_linop_clover_qphix_h__
7 #define __syssolver_linop_clover_qphix_h__
30 #include "qphix/geometry.h"
31 #include "qphix/qdp_packer.h"
32 #include "qphix/clover.h"
33 #include "qphix/invcg.h"
35 #include "qphix/invbicgstab.h"
45 namespace LinOpSysSolverQPhiXCloverEnv
59 using namespace QPhiXVecTraits;
61 template<
typename T,
typename U>
62 class LinOpSysSolverQPhiXClover :
public LinOpSystemSolver<T>
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;
77 LinOpSysSolverQPhiXClover(Handle< LinearOperator<T> > A_,
78 Handle< FermState<T,Q,Q> > state_,
79 const SysSolverQPhiXCloverParams& invParam_) :
82 QDPIO::cout <<
"LinOpSysSolverQPhiXClover:" << std::endl;
83 QDPIO::cout <<
"AntiPeriodicT is: " << invParam.AntiPeriodicT << std::endl;
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;
95 u[
mu] = state_->getLinks()[
mu];
99 multi1d<Real> aniso_coeffs(
Nd);
100 for(
int mu=0;
mu <
Nd;
mu++) aniso_coeffs[
mu] = Real(1);
102 bool anisotropy = invParam.CloverParams.anisoParam.anisoP;
104 aniso_coeffs =
makeFermCoeffs( invParam.CloverParams.anisoParam );
107 double t_boundary=(double)(1);
111 if (invParam.AntiPeriodicT) {
112 t_boundary=(double)(-1);
114 u[3] *= where(Layout::latticeCoordinate(3) == (Layout::lattSize()[3]-1),
115 Real(t_boundary), Real(1));
118 QDPIO::cout <<
"About to grap a Dslash" << std::endl;
119 const QPhiX::QPhiXCLIArgs& QPhiXParams = TheQPhiXParams::Instance();
120 cbsize_in_blocks = rb[0].numSiteTable() / VecTraits<REALT>::Soa;
126 int pad_xy = QPhiXParams.getPxy();
127 int pad_xyz = QPhiXParams.getPxyz();
130 geom =
new QPhiX::Geometry<REALT, VecTraits<REALT>::Vec, VecTraits<REALT>::Soa,VecTraits<REALT>::compress12>(Layout::subgridLattSize().slice(),
133 QPhiXParams.getNCores(),
138 QPhiXParams.getMinCt());
141 #ifndef QDP_IS_QDPJIT
142 QDPIO::cout <<
" Allocating p and c" << std::endl << std::flush ;
143 psi_qphix=(QPhiX_Spinor *)geom->allocCBFourSpinor();
144 chi_qphix=(QPhiX_Spinor *)geom->allocCBFourSpinor();
149 QDPIO::cout <<
" Allocating Clover" << std::endl << std::flush ;
150 QPhiX_Clover* A_cb0=(QPhiX_Clover *)geom->allocCBClov();
151 QPhiX_Clover* A_cb1=(QPhiX_Clover *)geom->allocCBClov();
152 clov_packed[0] = A_cb0;
153 clov_packed[1] = A_cb1;
155 QDPIO::cout <<
" Allocating CloverInv " << std::endl << std::flush ;
156 QPhiX_Clover* A_inv_cb0=(QPhiX_Clover *)geom->allocCBClov();
157 QPhiX_Clover* A_inv_cb1=(QPhiX_Clover *)geom->allocCBClov();
158 invclov_packed[0] = A_inv_cb0;
159 invclov_packed[1] = A_inv_cb1;
162 QDPIO::cout <<
"Packing gauge field..." << std::endl << std::flush ;
163 QPhiX_Gauge* packed_gauge_cb0=(QPhiX_Gauge *)geom->allocCBGauge();
164 QPhiX_Gauge* packed_gauge_cb1=(QPhiX_Gauge *)geom->allocCBGauge();
166 QPhiX::qdp_pack_gauge<>(
u, packed_gauge_cb0,packed_gauge_cb1, *geom);
167 u_packed[0] = packed_gauge_cb0;
168 u_packed[1] = packed_gauge_cb1;
171 QDPIO::cout <<
"Creating Clover Term" << std::endl;
173 clov->
create(state_, invParam.CloverParams);
174 QDPIO::cout <<
"Inverting Clover Term" << std::endl;
175 invclov->create(state_, invParam.CloverParams, (*clov));
176 for(
int cb=0;
cb < 2;
cb++) {
179 QDPIO::cout <<
"Done" << std::endl;
180 QDPIO::cout <<
"Packing Clover term..." << std::endl;
182 for(
int cb=0;
cb < 2;
cb++) {
183 QPhiX::qdp_pack_clover<>((*invclov), invclov_packed[
cb], *geom,
cb);
186 for(
int cb=0;
cb < 2;
cb++) {
187 QPhiX::qdp_pack_clover<>((*clov), clov_packed[
cb], *geom,
cb);
189 QDPIO::cout <<
"Done" << std::endl;
191 QDPIO::cout <<
"Creating the Even Odd Operator" << std::endl;
192 M=
new QPhiX::EvenOddCloverOperator<REALT,VecTraits<REALT>::Vec,VecTraits<REALT>::Soa,VecTraits<REALT>::compress12>(u_packed,
197 toDouble(aniso_coeffs[0]),
198 toDouble(aniso_coeffs[3]));
201 switch( invParam.SolverType ) {
204 QDPIO::cout <<
"Creating the CG Solver" << std::endl;
205 cg_solver =
new QPhiX::InvCG<REALT,VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12>((*M), invParam.MaxIter);
211 QDPIO::cout <<
"Creating the BiCGStab Solver" << std::endl;
212 bicgstab_solver =
new QPhiX::InvBiCGStab<REALT,VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12>((*M), invParam.MaxIter);
216 QDPIO::cerr <<
"UNKNOWN Solver Type" << std::endl;
224 ~LinOpSysSolverQPhiXClover()
228 QDPIO::cout <<
"Destructing" << std::endl;
230 #ifndef QDP_IS_QDPJIX
231 geom->free(psi_qphix);
232 geom->free(chi_qphix);
237 geom->free(invclov_packed[0]);
238 geom->free(invclov_packed[1]);
239 invclov_packed[0] =
nullptr;
240 invclov_packed[1] =
nullptr;
242 geom->free(clov_packed[0]);
243 geom->free(clov_packed[1]);
244 clov_packed[0] =
nullptr;
245 clov_packed[1] =
nullptr;
247 geom->free(u_packed[0]);
248 geom->free(u_packed[1]);
249 u_packed[0] =
nullptr;
250 u_packed[1] =
nullptr;
258 const Subset& subset()
const {
return A->subset();}
271 SystemSolverResults_t res;
272 switch( invParam.SolverType ) {
280 res = biCGStabSolve(
psi,
chi);
284 QDPIO::cout <<
"Unknown Solver " << std::endl;
297 LinOpSysSolverQPhiXClover() {}
301 Handle< LinearOperator<T> >
A;
302 const SysSolverQPhiXCloverParams invParam;
303 Handle< CloverTermT<T, U> > clov;
304 Handle< CloverTermT<T, U> > invclov;
306 QPhiX::Geometry<REALT, VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12>* geom;
308 Handle< QPhiX::EvenOddCloverOperator<REALT, VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12> > M;
311 Handle< QPhiX::InvCG<REALT,VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12> > cg_solver;
313 Handle< QPhiX::InvBiCGStab<REALT,VecTraits<REALT>::Vec, VecTraits<REALT>::Soa, VecTraits<REALT>::compress12> > bicgstab_solver;
315 QPhiX_Clover* invclov_packed[2];
316 QPhiX_Clover* clov_packed[2];
317 QPhiX_Gauge* u_packed[2];
319 mutable QPhiX_Spinor* psi_qphix;
320 mutable QPhiX_Spinor* chi_qphix;
321 size_t cbsize_in_blocks;
323 SystemSolverResults_t cgnrSolve(
T&
psi,
const T&
chi)
const
326 SystemSolverResults_t res;
338 #ifndef QDP_IS_QDPJIT
339 QPhiX::qdp_pack_cb_spinor<>(
psi, psi_qphix, *geom,1);
340 QPhiX::qdp_pack_cb_spinor<>(mdag_chi, chi_qphix, *geom,1);
342 psi_qphix = (QPhiX_Spinor*)(
psi.getFjit()) + cbsize_in_blocks;
343 chi_qphix = (QPhiX_Spinor*)(
chi.getFjit()) + cbsize_in_blocks;
347 unsigned long site_flops=0;
348 unsigned long mv_apps=0;
351 double start = omp_get_wtime();
352 (*cg_solver)(psi_qphix,chi_qphix, toDouble(invParam.RsdTarget), res.n_count, rsd_final, site_flops, mv_apps, my_isign,invParam.VerboseP);
353 double end = omp_get_wtime();
355 QDPIO::cout <<
"QPHIX_CLOVER_CG_SOLVER: " << res.n_count <<
" iters, rsd_sq_final=" << rsd_final << std::endl;
356 #ifndef QDP_IS_QDPJIT
357 QPhiX::qdp_unpack_cb_spinor<>(psi_qphix,
psi,*geom,1);
365 r[
A->subset() ] -=
tmp;
369 Double rel_resid = sqrt(r2/b2);
371 QDPIO::cout <<
"QPHIX_CLOVER_CG_SOLVER: || r || / || b || = " << rel_resid << std::endl;
374 if ( !toBool ( rel_resid < invParam.RsdTarget*invParam.RsdToleranceFactor ) ) {
375 QDPIO::cout <<
"SOLVE FAILED" << std::endl;
380 int num_cb_sites = Layout::vol()/2;
381 unsigned long total_flops = (site_flops + (1320+504+1320+504+48)*mv_apps)*num_cb_sites;
382 double gflops = (double)(total_flops)/(1.0e9);
384 double total_time = end - start;
385 QDPIO::cout <<
"QPHIX_CLOVER_CG_SOLVER: Solver Time="<< total_time <<
" (sec) Performance=" << gflops / total_time <<
" GFLOPS" << std::endl;
392 SystemSolverResults_t biCGStabSolve(
T&
psi,
const T&
chi)
const
394 SystemSolverResults_t res;
398 #ifndef QDP_IS_QDPJIT
399 QDPIO::cout <<
"Packing" << std::endl << std::flush ;
400 QPhiX::qdp_pack_cb_spinor<>(
psi, psi_qphix, *geom,1);
401 QPhiX::qdp_pack_cb_spinor<>(
chi, chi_qphix, *geom,1);
402 QDPIO::cout <<
"Done" << std::endl << std::flush;
404 psi_qphix = (QPhiX_Spinor *)(
psi.getFjit())+cbsize_in_blocks;
405 chi_qphix = (QPhiX_Spinor *)(
chi.getFjit())+cbsize_in_blocks;
409 unsigned long site_flops=0;
410 unsigned long mv_apps=0;
412 QDPIO::cout <<
"Starting solve" << std::endl << std::flush ;
413 double start = omp_get_wtime();
414 (*bicgstab_solver)(psi_qphix,chi_qphix, toDouble(invParam.RsdTarget), res.n_count, rsd_final, site_flops, mv_apps, 1, invParam.VerboseP);
415 double end = omp_get_wtime();
417 QDPIO::cout <<
"QPHIX_CLOVER_BICGSTAB_SOLVER: " << res.n_count <<
" iters, rsd_sq_final=" << rsd_final << std::endl;
419 #ifndef QDP_IS_QDPJIT
420 QPhiX::qdp_unpack_cb_spinor<>( psi_qphix,
psi, *geom,1);
428 r[
A->subset() ] -=
tmp;
432 Double rel_resid = sqrt(r2/b2);
434 QDPIO::cout <<
"QPHIX_CLOVER_BICGSTAB_SOLVER: || r || / || b || = " << rel_resid << std::endl;
437 if ( !toBool ( rel_resid < invParam.RsdTarget*invParam.RsdToleranceFactor ) ) {
438 QDPIO::cout <<
"SOLVE FAILED" << std::endl;
443 int num_cb_sites = Layout::vol()/2;
444 unsigned long total_flops = (site_flops + (1320+504+1320+504+48)*mv_apps)*num_cb_sites;
445 double gflops = (double)(total_flops)/(1.0e9);
447 double total_time = end - start;
448 QDPIO::cout <<
"QPHIX_CLOVER_BICGSTAB_SOLVER: Solver Time="<< total_time <<
" (sec) Performance=" << gflops / total_time <<
" GFLOPS" << std::endl;
void create(Handle< FermState< T, multi1d< U >, multi1d< U > > > fs, const CloverFermActParams ¶m_)
Creation routine.
Include possibly optimized Clover terms.
Even-odd preconditioned Clover fermion linear operator.
Class for counted reference semantics.
bool registerAll()
Register all the factories.
multi1d< Hadron2PtContraction_t > operator()(const multi1d< LatticeColorMatrix > &u)
Asqtad Staggered-Dirac operator.
static multi1d< LatticeColorMatrix > u
LinOpSysSolverMGProtoClover::Q Q
QDPCloverTermT< T, U > CloverTermT
multi1d< Real > makeFermCoeffs(const AnisoParam_t &aniso)
Make fermion coefficients.
FloatingPoint< double > Double
multi1d< LatticeFermion > r(Ncb)
Periodic ferm state and a creator.
Fermion action factories.
Reunitarize in place a color matrix to SU(N)
Support class for fermion actions and linear operators.
multi1d< LatticeColorMatrix > U
multi1d< LatticeColorMatrix > Q