14 #if BASE_PRECISION == 32
15 #define QDP_Precision 'F'
16 #define QLA_Precision 'F'
17 #define toReal toFloat
18 #elif BASE_PRECISION == 64
19 #define QDP_Precision 'D'
20 #define QLA_Precision 'D'
21 #define toReal toDouble
28 #include "wilsonmg-interface.h"
29 extern struct MGP(Clover_Params) PC(g_param);
39 static multi1d<LatticeColorMatrix>
u;
44 #define index(c) c[0]+nrow[0]/2*(c[1]+nrow[1]*(c[2]+nrow[2]*(c[3]+nrow[3]*((c[0]+c[1]+c[2]+c[3])%2))))
46 void peekpoke##d(QLA(ColorMatrix) *dest, int coords[]) {\
48 multi1d<int> x(4); for (int i=0; i<4; i++) x[i] = coords[i];\
49 ColorMatrix U; U.elem() = u[d].elem(Layout::linearSiteIndex(x));\
53 QLA(Real) real, imag;\
54 for (int c1=0; c1<3; c1++)\
55 for (int c2=0; c2<3; c2++) {\
56 real = U.elem().elem().elem(c1,c2).real();\
57 imag = U.elem().elem().elem(c1,c2).imag();\
58 if (0&&c1==0&&c2==0) {std::fflush(stdout);printf("Chroma: gauge[%d] I am node %d, parsing %d %d %d %d; I see %g + I %g\n",d,Layout::nodeNumber(),x[0],x[1],x[2],x[3],real,imag); std::fflush(stdout);}\
59 QLA(C_eq_R_plus_i_R)(&z, &real, &imag);\
60 QLA_elem_M(*dest,c1,c2) = z;\
74 A(A_),
state(state_), invParam(invParam_), subspace(0x0)
77 for (
int d=0;
d<4;
d++) PC(g_param).bc[
d] = 1;
78 PC(g_param).aniso_xi = toReal(invParam.AnisoXi);
79 PC(g_param).aniso_nu = toReal(invParam.AnisoNu);
80 PC(g_param).kappa = toReal(invParam.Kappa);
81 PC(g_param).kappac = toReal(invParam.KappaCrit);
82 PC(g_param).mass = toReal(invParam.Mass);
83 PC(g_param).massc = toReal(invParam.MassCrit);
84 PC(g_param).clov_s = toReal(invParam.Clover);
85 PC(g_param).clov_t = toReal(invParam.CloverT);
86 PC(g_param).res = toReal(invParam.Residual);
87 PC(g_param).ngcr = invParam.NumGCRVecs;
88 PC(g_param).maxiter = invParam.MaxIter;
89 PC(g_param).verb = invParam.Verbose;
90 PC(g_param).levels = invParam.Levels;
92 for (
int n=0;
n<invParam.Levels;
n++) {
93 for (
int d=0;
d<4;
d++)
94 PC(g_param).block[
n][
d] = invParam.Blocking[
n][
d];
95 PC(g_param).nNullVecs[
n] = invParam.NumNullVecs[
n];
96 PC(g_param).nullMaxIter[
n] = invParam.NullMaxIter[
n];
97 PC(g_param).nullRes[
n] = toReal(invParam.NullResidual[
n]);
98 PC(g_param).nullConv[
n] = toReal(invParam.NullConvergence[
n]);
99 PC(g_param).nExtraVecs[
n] = invParam.NumExtraVecs[
n];
100 PC(g_param).urelax[
n] = toReal(invParam.Underrelax[
n]);
101 PC(g_param).npre[
n] = invParam.NumPreHits[
n];
102 PC(g_param).npost[
n] = invParam.NumPostHits[
n];
103 PC(g_param).cngcr[
n] = invParam.CoarseNumGCRVecs[
n];
104 PC(g_param).cmaxiter[
n] = invParam.CoarseMaxIter[
n];
105 PC(g_param).cres[
n] = toReal(invParam.CoarseResidual[
n]);
110 if (invParam.Levels>0) {
115 u = state_->getLinks();
122 QDPIO::cout <<
"Plaquette from State: " << std::endl;
123 QDPIO::cout <<
" w_plaq = " <<
w_plaq << std::endl;
124 QDPIO::cout <<
" s_plaq = " <<
s_plaq << std::endl;
125 QDPIO::cout <<
" t_plaq = " <<
t_plaq << std::endl;
126 QDPIO::cout <<
" link trace = " <<
link << std::endl;
129 int machsize[4], latsize[4];
130 for (
int d=0;
d<4;
d++) machsize[
d] = Layout::logicalSize()[
d];
131 for (
int d=0;
d<4;
d++) latsize[
d] = Layout::lattSize()[
d];
132 void (*peekpoke[4])(QLA(ColorMatrix) *dest,
int coords[]) =
133 {peekpoke0,peekpoke1,peekpoke2,peekpoke3};
140 LinOpSysSolverQOPMG::
141 ~LinOpSysSolverQOPMG()
144 if ( !invParam.ExternalSubspace ) {
145 if ( subspace != 0x0 )
MGP(destroy_subspace)(subspace);
157 Fermion src; src.elem() = ((
T*)vec_src)->elem(Layout::linearSiteIndex(
x));
165 QLA(Real) real, imag;
166 for (
int s=0;
s<4;
s++)
167 for (
int c=0;
c<3;
c++) {
168 real = src.elem().elem(
s).elem(
c).real();
169 imag = src.elem().elem(
s).elem(
c).imag();
171 QLA(C_eq_R_plus_i_R)(&
z, &real, &imag);
172 QLA(elem_D)(*dest,
c,
s) =
z;
193 Fermion src; src.elem() = ((
T*)
fermionsrc)->elem(Layout::linearSiteIndex(
x));
200 QLA(Real) real, imag;
201 for (
int s=0;
s<4;
s++)
202 for (
int c=0;
c<3;
c++) {
203 real = src.elem().elem(
s).elem(
c).real();
204 imag = src.elem().elem(
s).elem(
c).imag();
206 QLA(C_eq_R_plus_i_R)(&
z, &real, &imag);
207 QLA(elem_D)(*dest,
c,
s) =
z;
224 QLA(Real) real, imag;
225 for (
int s=0;
s<4;
s++) {
226 for (
int c=0;
c<3;
c++) {
227 z = QLA_elem_D(*src,
c,
s);
228 QLA(R_eq_re_C)(&real, &
z);
229 QLA(R_eq_im_C)(&imag, &
z);
230 Complex ztmp = cmplx(Real(real), Real(imag));
231 pokeColor(ctmp, ztmp,
c);
233 pokeSpin(ftmp, ctmp,
s);
244 SystemSolverResults_t
255 int machsize[4], latsize[4];
256 for (
int d=0;
d<4;
d++) machsize[
d] = Layout::logicalSize()[
d];
257 for (
int d=0;
d<4;
d++) latsize[
d] = Layout::lattSize()[
d];
270 QDPIO::cout <<
"Chroma: chi all norm2 = " << bsq << std::endl;
273 res.
n_count =
MGP(solve)(peekpokesrc<T>, peekpokeguess<T>, peekpokesol<T>,solve_subspace);
275 bsq = norm2(
psi,all);
276 QDPIO::cout <<
"Chroma: psi all norm2 = " << bsq << std::endl;
279 double time = swatch.getTimeInSeconds();
282 r[
A->subset()] =
chi;
285 r[
A->subset()] -=
tmp;
286 res.
resid = sqrt(norm2(
r,
A->subset()));
287 rel_resid = res.
resid / sqrt(norm2(
chi,
A->subset()));
290 QDPIO::cout <<
"QOPMG_LINOP_SOLVER: "
291 <<
" Mass: " << invParam.Mass
292 <<
" iterations: " << res.
n_count
293 <<
" time: " << time <<
" secs"
294 <<
" Rsd: " << res.
resid
295 <<
" Relative Rsd: " << rel_resid
298 if ( invParam.TerminateOnFail ) {
299 if ( toBool( rel_resid >= invParam.RsdToleranceFactor*invParam.Residual ) ) {
300 QDPIO::cout <<
"!!!!! QOPMG_LINOP_SOLVER: "
301 <<
"Mass: " << invParam.Mass
302 <<
" did NOT CONVERGE: Target RelRsd = " << invParam.Residual
303 <<
" Actual RelRsd = " << rel_resid << std::endl;
304 QDPIO::cout <<
"Exiting !!!!! " << std::endl;
317 int machsize[4], latsize[4];
318 for (
int d=0;
d<4;
d++) machsize[
d] = Layout::logicalSize()[
d];
319 for (
int d=0;
d<4;
d++) latsize[
d] = Layout::lattSize()[
d];
321 QDPIO::cout <<
"LinOpSysSolverQOPMG::getSubspace() " << std::endl;
322 if( !invParam.ExternalSubspace ) {
324 QDPIO::cout <<
"Internal doesn't yet exist... creating" << std::endl;
331 if( TheNamedObjMap::Instance().check(invParam.SubspaceId) ) {
332 QDPIO::cout <<
"Retreiving Subspace Pointer from NamedObject Map" << endl;
333 ret_val = TheNamedObjMap::Instance().getData<
WilsonMGSubspace * >(invParam.SubspaceId);
334 MGP(reset_subspace)(latsize,ret_val);
337 QDPIO::cout <<
"Using External Subspace but object ID: " << invParam.SubspaceId <<
" is not present in the NamedObject store." << std:: endl;
338 QDPIO::cout <<
"Creating a new one" << std::endl;
341 QDPIO::cout <<
"Saving in Map" << std::endl;
342 QDPIO::cout <<
"Creating Named Object Map Entry for subspace" << std::endl;
343 XMLBufferWriter file_xml;
344 push(file_xml,
"FileXML");
347 XMLBufferWriter record_xml;
348 push(record_xml,
"RecordXML");
349 write(record_xml,
"InvertParam", invParam);
352 TheNamedObjMap::Instance().create<
WilsonMGSubspace *>(invParam.SubspaceId);
353 TheNamedObjMap::Instance().get(invParam.SubspaceId).setFileXML(file_xml);
354 TheNamedObjMap::Instance().get(invParam.SubspaceId).setRecordXML(record_xml);
355 TheNamedObjMap::Instance().getData<
WilsonMGSubspace*>(invParam.SubspaceId)=ret_val;
362 void LinOpSysSolverQOPMG::eraseSubspace()
364 QDPIO::cout <<
"LinOpSysSolverQOPMG: Erasing Subspace" << endl;
365 if( !invParam.ExternalSubspace ) {
367 QDPIO::cout <<
"My subspace does not come from the NamedObjMap" << std::endl;
370 if ( subspace != 0x0 ) {
371 QDPIO::cout <<
"My subspace pointer is not null... Destroying"
374 MGP(destroy_subspace)(subspace);
380 if ( TheNamedObjMap::Instance().check(invParam.SubspaceId) ) {
381 QDPIO::cout <<
"MG Subspace: " << invParam.SubspaceId <<
" found. " << std::endl;
385 MGP(destroy_subspace)(named_obj_subspace);
387 QDPIO::cout <<
"Attempting to delete from named object store" << std:: endl;
389 TheNamedObjMap::Instance().erase(invParam.SubspaceId);
391 QDPIO::cout <<
"Object erased" << std::endl;
393 catch( std::bad_cast ) {
394 QDPIO::cerr <<
" MGMdagMInternal::eraseSubspace: cast error"
400 QDPIO::cerr <<
" MGMdagMInternal::eraseSubspace: error message: " << e
405 QDPIO::cout <<
"Subspace: " << invParam.SubspaceId <<
" destroyed and removed from map" << std::endl;
408 QDPIO::cout <<
"MG Subspace: " << invParam.SubspaceId <<
" is not in the map. Nothing to desroy" << std::endl;
414 namespace LinOpSysSolverQOPMGEnv
432 multi1d<LatticeColorMatrix>,
433 multi1d<LatticeColorMatrix> > >
state,
Support class for fermion actions and linear operators.
Class for counted reference semantics.
Solve a M*psi=chi linear system using the external QDP multigrid inverter.
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams ¶m)
Writer parameters.
Named object function std::map.
static bool registered
Local registration flag.
const std::string name
Name to be used.
multi1d< int > coords(const int x, const int y, const int z, const int t)
LinOpSystemSolver< LatticeFermion > * createFerm(XMLReader &xml_in, const std::string &path, Handle< FermState< LatticeFermion, multi1d< LatticeColorMatrix >, multi1d< LatticeColorMatrix > > > state, Handle< LinearOperator< LatticeFermion > > A)
Callback function for standard precision.
bool registerAll()
Register all the factories.
MGSubspacePointers * create_subspace(const SysSolverQUDAMULTIGRIDCloverParams &invParam)
multi1d< Hadron2PtContraction_t > operator()(const multi1d< LatticeColorMatrix > &u)
Asqtad Staggered-Dirac operator.
static multi1d< LatticeColorMatrix > u
void peekpokesrc(QLA(DiracFermion) *dest, int coords[])
LinOpSysSolverMGProtoClover::T T
void peekpokeguess(QLA(DiracFermion) *dest, int coords[])
void initialize(int *argc, char ***argv)
Chroma initialisation routine.
void finalize(void)
Chroma finalization routine.
void peekpokesol(QLA(DiracFermion) *src, int coords[])
void MesPlq(const multi1d< LatticeColorMatrixF3 > &u, multi2d< Double > &plane_plaq, Double &link)
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > state
void importFermion(QLA(DiracFermion) *dest, T *vec_src, int coords[])
FloatingPoint< double > Double
multi1d< LatticeFermion > r(Ncb)
Support class for fermion actions and linear operators.
Parameters for the external QDP multigrid inverter.
Holds return info from SystemSolver call.
Register linop system solvers that solve M*psi=chi.
Factory for solving M*psi=chi where M is not hermitian or pos. def.
struct MGP(Clover_Params) PC(g_param)
Make contact with the QDP clover multigrid solver, transfer the gauge field, generate the coarse grid...
push(xml_out,"Cooled_Topology")