11 #include <qop-mdwf3.h>
22 namespace LinOpSysSolverMDWFArrayEnv
29 multi1d<LatticeColorMatrix>,
30 multi1d<LatticeColorMatrix>
70 const int latt_coord[4],
78 multi1d<LatticeColorMatrix>&
u = *(multi1d<LatticeColorMatrix>*)env;
83 int node = Layout::nodeNumber(
coord);
84 int linear = Layout::linearSiteIndex(
coord);
86 if (node != Layout::nodeNumber()) {
88 QDPIO::cerr << __func__ <<
": wrong coordinates for this node" << std::endl;
96 double val = (reim == 0) ?
97 toDouble(
u[
mu].elem(linear).elem().elem(row,col).real()) :
98 toDouble(
u[
mu].elem(linear).elem().elem(row,col).imag());
108 double fermionReader(
const int latt_coord[5],
117 multi1d<LatticeFermion>&
psi = *(multi1d<LatticeFermion>*)env;
120 int s = latt_coord[
Nd];
123 int node = Layout::nodeNumber(
coord);
124 int linear = Layout::linearSiteIndex(
coord);
126 if (node != Layout::nodeNumber()) {
128 QDPIO::cerr << __func__ <<
": wrong coordinates for this node" << std::endl;
136 double val = (reim == 0) ?
137 double(
psi[
s].elem(linear).elem(spin).elem(color).real()) :
138 double(
psi[
s].elem(linear).elem(spin).elem(color).imag());
151 void fermionWriter(
const int latt_coord[5],
162 multi1d<LatticeFermion>&
psi = *(multi1d<LatticeFermion>*)env;
165 int s = latt_coord[
Nd];
168 int node = Layout::nodeNumber(
coord);
169 int linear = Layout::linearSiteIndex(
coord);
171 if (node != Layout::nodeNumber()) {
172 QDPIO::cerr << __func__ <<
": wrong coordinates for this node" << std::endl;
187 psi[
s].elem(linear).elem(spin).elem(color).real() = val;
189 psi[
s].elem(linear).elem(spin).elem(color).imag() = val;
196 void sublattice_func(
int lo[],
207 const multi1d<int>& local_subgrid=Layout::subgridLattSize();
208 for(
int i=0;
i <
Nd;
i++) {
211 lo[
i]=node[
i]*local_subgrid[
i];
216 hi[
i]=(node[
i]+1)*local_subgrid[
i];
231 const multi1d<LatticeFermion>&
chi)
const
237 int out_iters_single=0;
238 int out_iters_double=0;
249 double out_eps_single;
253 QOP_F3_MDWF_Gauge *sprec_gauge = NULL;
254 if ( QOP_F3_MDWF_import_gauge(&sprec_gauge,
258 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
263 QOP_F3_MDWF_Fermion *sprec_rhs;
264 QOP_F3_MDWF_Fermion *sprec_x0;
265 QOP_F3_MDWF_Fermion *sprec_soln;
267 if( QOP_F3_MDWF_import_fermion(&sprec_rhs,
270 (
void *)&
chi) != 0 ) {
271 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
275 if( QOP_F3_MDWF_import_fermion(&sprec_x0,
278 (
void *)&
psi) != 0 ) {
279 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
283 if( QOP_F3_MDWF_allocate_fermion(&sprec_soln,
285 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
291 double target_epsilon = toDouble(invParam.RsdTarget*invParam.RsdTarget);
292 int max_iteration = invParam.MaxIter;
295 QDPIO::cout <<
"LinOpSysSolverMDWFArray: Beginning Single Precision Solve" << std::endl;
296 if( ( status=QOP_F3_MDWF_DDW_CG(sprec_soln,
305 QOP_MDWF_LOG_NONE)) != 0 ) {
306 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
311 if( QOP_MDWF_performance(&time_sec,
316 QDPIO::cerr <<
"MDWF_Error: "<< QOP_MDWF_error(
state) << std::endl;
321 QDPIO::cout <<
"LinOpSysSolverMDWFArray Single Prec : status=" << status
322 <<
" iterations=" << out_iters_single
323 <<
" resulting epsilon=" << sqrt(out_eps_single) << std::endl;
326 FlopCounter flopcount_single;
327 flopcount_single.reset();
328 flopcount_single.addFlops(flops);
329 flopcount_single.report(
"LinOpSysSolverMDWFArray_Single_Prec:", time_sec);
332 if( QOP_F3_MDWF_export_fermion(fermionWriter,
335 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
340 QOP_F3_MDWF_free_fermion(&sprec_soln);
341 QOP_F3_MDWF_free_fermion(&sprec_x0);
342 QOP_F3_MDWF_free_fermion(&sprec_rhs);
343 QOP_F3_MDWF_free_gauge(&sprec_gauge);
345 res.
n_count = out_iters_single;
351 double out_eps_double;
355 QOP_D3_MDWF_Gauge *dprec_gauge = NULL;
356 if ( QOP_D3_MDWF_import_gauge(&dprec_gauge,
360 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
365 QOP_D3_MDWF_Fermion *dprec_rhs;
366 QOP_D3_MDWF_Fermion *dprec_x0;
367 QOP_D3_MDWF_Fermion *dprec_soln;
369 if( QOP_D3_MDWF_import_fermion(&dprec_rhs,
372 (
void *)&
chi) != 0 ) {
373 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
377 if( QOP_D3_MDWF_import_fermion(&dprec_x0,
380 (
void *)&
psi) != 0 ) {
381 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
385 if( QOP_D3_MDWF_allocate_fermion(&dprec_soln,
387 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
392 double target_epsilon = toDouble(invParam.RsdTargetRestart*invParam.RsdTargetRestart);
393 int max_iteration = invParam.MaxIterRestart;
397 QDPIO::cout <<
"LinOpSysSolverMDWFArray: Beginning Double Precision Solve" << std::endl;
398 if( ( status=QOP_D3_MDWF_DDW_CG(dprec_soln,
407 QOP_MDWF_LOG_NONE)) != 0 ) {
408 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
413 if( QOP_MDWF_performance(&time_sec,
418 QDPIO::cerr <<
"MDWF_Error: "<< QOP_MDWF_error(
state) << std::endl;
422 QDPIO::cout <<
"LinOpSysSolverMDWFArray Double Prec: status=" << status
423 <<
" iterations=" << out_iters_double
424 <<
" resulting epsilon=" << sqrt(out_eps_double) << std::endl;
427 FlopCounter flopcount_double;
428 flopcount_double.reset();
429 flopcount_double.addFlops(flops);
430 flopcount_double.report(
"LinOpSysSolverMDWFArray_Double_Prec:", time_sec);
433 if( QOP_D3_MDWF_export_fermion(fermionWriter,
436 QDPIO::cerr <<
"MDWF Error: "<< QOP_MDWF_error(
state) << std::endl;
441 QOP_D3_MDWF_free_fermion(&dprec_soln);
442 QOP_D3_MDWF_free_fermion(&dprec_x0);
443 QOP_D3_MDWF_free_fermion(&dprec_rhs);
444 QOP_D3_MDWF_free_gauge(&dprec_gauge);
447 res.
n_count += out_iters_double;
452 multi1d<LatticeFermion>
r(invParam.N5);
455 res.
resid = sqrt(norm2(
r));
457 QDPIO::cout <<
"MDWF Final: single_iters=" << out_iters_single <<
" double_iters=" << out_iters_double <<
" total_iters=" << res.
n_count << std::endl;
458 QDPIO::cout <<
"MDWF Final: final absolute unprec residuum="<<res.
resid<<std::endl;
471 QDPIO::cout <<
"This will only work for Nd=4" << std::endl;
476 QDPIO::cout <<
"This will only work for Nc=3" << std::endl;
484 multi1d<int> lattice(5);
485 multi1d<int> network(4);
486 multi1d<int> node_coords(4);
491 lattice[
mu] = Layout::lattSize()[
mu];
493 lattice[
Nd]=invParam.N5;
496 network[
mu] = Layout::logicalSize()[
mu];
497 node_coords[
mu] = Layout::nodeCoord()[
mu];
502 if( Layout::primaryNode() ) {
510 QDPIO::cout <<
"LinOpSysSolverMDWFArray: Initializing MDWF Library Version " << QOP_MDWF_version() << std::endl;
513 if( QOP_MDWF_init(&
state, lattice.slice(), network.slice(),
514 node_coords.slice(), master_p, sublattice_func,
517 QDPIO::cerr <<
"MDWF Error: " << QOP_MDWF_error(
state) << std::endl;
523 u = fermstate->getLinks();
526 if (invParam.anisoParam.anisoP) {
527 ff = where(invParam.anisoParam.anisoP, invParam.anisoParam.nu / invParam.anisoParam.xi_0, Real(1));
528 for(
int mu=0;
mu <
u.size(); ++
mu) {
529 if (
mu != invParam.anisoParam.t_dir)
536 double a5 = (double)1;
541 double M5 = (double)(-5) + toDouble((
double)1 +
a5*((
double)1 + (
double)(
Nd-1)*ff - invParam.OverMass));
543 double m_f = toDouble(invParam.Mass);
546 if( QOP_MDWF_set_generic(&
params,
551 QDPIO::cerr <<
"MDWF Error: " << QOP_MDWF_error(
state)<< std::endl;
563 void LinOpSysSolverMDWFArray::fini(
void)
566 QDPIO::cout <<
"MDWFQpropT: Finalizing MDWF Library Version " << QOP_MDWF_version() << std::endl;
569 QOP_MDWF_free_parameters(&
params);
573 QOP_MDWF_fini(&
state);
Support class for fermion actions and linear operators.
Class for counted reference semantics.
AVP's DWF Solver interface.
Linear Operator to arrays.
double gaugeReader(const void *OuterGauge, void *env, const int latt_coord[4], int mu, int row, int col, int reim)
static bool registered
Local registration flag.
const std::string name("MDWF_INVERTER")
Name to be used.
LinOpSystemSolverArray< LatticeFermion > * createFerm(XMLReader &xml_in, const std::string &path, Handle< FermState< LatticeFermion, multi1d< LatticeColorMatrix >, multi1d< LatticeColorMatrix > > > state, Handle< LinearOperatorArray< LatticeFermion > > A)
Callback function.
bool registerAll()
Register all the factories.
void init(MesonSpecData_t &data, XMLWriter &xml, const std::string &path, const std::string &id_tag, const Params ¶ms)
Do some initialization.
multi1d< Hadron2PtContraction_t > operator()(const multi1d< LatticeColorMatrix > &u)
Asqtad Staggered-Dirac operator.
static multi1d< LatticeColorMatrix > u
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > state
multi1d< LatticeFermion > r(Ncb)
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.
DWF/SSE double-prec solver.