CHROMA
lwldslash_w_qphix.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! \file
3  * \brief Wilson Dslash linear operator
4  */
5 
6 #ifndef __lwldslash_qphix_h__
7 #define __lwldslash_qphix_h__
8 
9 #include "qphix_singleton.h"
10 
11 #ifdef CHROMA_BUILDING_QPHIX_DSLASH
12 #warning USING QPHIX DSLASH
13 #undef DEBUG_QPHIX_DSLASH
14 
15 
16 #include "chroma_config.h"
18 #include "io/aniso_io.h"
19 #include "state.h"
20 #include "qdp_datalayout.h"
21 #include "qphix/geometry.h"
22 #include "qphix/dslash_def.h"
23 #include "qphix/qdp_packer.h"
25 
26 
27 
28 #ifdef S
29 warning "S is defined"
30 #endif
31 
32 namespace Chroma
33 {
34  //! General Wilson-Dirac dslash
35  /*!
36  * \ingroup linop
37  *
38  * DSLASH
39  *
40  * This routine is specific to Wilson fermions!
41  *
42  * Description:
43  *
44  * This routine applies the operator D' to Psi, putting the result in Chi.
45  *
46  * Nd-1
47  * ---
48  * \
49  * chi(x) := > U (x) (1 - isign gamma ) psi(x+mu)
50  * / mu mu
51  * ---
52  * mu=0
53  *
54  * Nd-1
55  * ---
56  * \ +
57  * + > U (x-mu) (1 + isign gamma ) psi(x-mu)
58  * / mu mu
59  * ---
60  * mu=0
61  *
62  */
63  template<typename T,typename P, typename Q>
64  class QPhiXWilsonDslash : public WilsonDslashBase<T,P,Q>
65  {
66  public:
67  // Floating Type <float or double>
68  using FT = typename WordType<T>::Type_t;
69 
70  // Save fingers...
71  template<typename TT>
72  using VecTraits = Chroma::QPhiXVecTraits::VecTraits<TT>;
73 
74  // Geometry Type
75  using Geom = typename QPhiX::Geometry<FT,VecTraits<FT>::Vec, VecTraits<FT>::Soa, false>;
76 
77  // Dslash Type
78  // FIXME: IT is possible that some noddy user applies this to a non SU(3) field. It should still
79  // Give the same result as a regular Dslash, so I will for safety set the compress to false here.
80  using Dsl = typename QPhiX::Dslash<FT,VecTraits<FT>::Vec, VecTraits<FT>::Soa, false>;
81 
82  // Spinor and Gauge Types
83  using Spinor = typename Geom::FourSpinorBlock;
84  using Gauge = typename Geom::SU3MatrixBlock;
85 
86 
87 
88  public:
89  //! Empty constructor. Must use create later
90 
91  // Originally had constructor args: : theGeom(nullptr), theDslash(nullptr), packed_gauge{nullptr,nullptr}
92  // But now these are static
93  QPhiXWilsonDslash()
94 #ifndef CHROMA_STATIC_PACKED_GAUGE
95  : packed_gauge{nullptr,nullptr}
96 #endif
97  {}
98 
99 
100 
101 
102  //! Full constructor
103  // Originally had constructor args: : theGeom(nullptr), theDslash(nullptr), packed_gauge{nullptr,nullptr}
104  // But now these are static
105  QPhiXWilsonDslash(Handle< FermState<T,P,Q> > state)
106 #ifndef CHROMA_STATIC_PACKED_GAUGE
107  : packed_gauge{nullptr,nullptr}
108 #endif
109  {
110  create(state);
111  }
112 
113  //! Full constructor with anisotropy
114  // Originally had constructor args: : theGeom(nullptr), theDslash(nullptr), packed_gauge{nullptr,nullptr}
115  // But now these are static
116  QPhiXWilsonDslash(Handle< FermState<T,P,Q> > state,
117  const AnisoParam_t& aniso_)
118 #ifndef CHROMA_STATIC_PACKED_GAUGE
119  : packed_gauge{nullptr,nullptr}
120 #endif
121  {
122  create(state,aniso_);
123  }
124 
125  //! Full constructor with general coefficients
126  // Originally had constructor args: : theGeom(nullptr), theDslash(nullptr), packed_gauge{nullptr,nullptr}
127  // But now these are static
128  QPhiXWilsonDslash(Handle< FermState<T,P,Q> > state,
129  const multi1d<Real>& coeffs_)
130 #ifndef CHROMA_STATIC_PACKED_GAUGE
131  : packed_gauge{nullptr,nullptr}
132 #endif
133  {
134  create(state,coeffs_);
135  }
136 
137  //! Creation routine
138  void create(Handle< FermState<T,P,Q> > state)
139  {
140  multi1d<Real> cf(Nd);
141  cf = 1.0;
142  create(state, cf);
143  }
144  //! Creation routine with anisotropy
145  void create(Handle< FermState<T,P,Q> > state,
146  const AnisoParam_t& aniso_) {
147  START_CODE();
148 
149  create(state, makeFermCoeffs(aniso_));
150  END_CODE();
151  }
152 
153  //! Full constructor with general coefficients
154  void create(Handle< FermState<T,P,Q> > state, const multi1d<Real>& coeffs_) {
155  START_CODE();
156 
157 
158  // Save a copy of the fermbc
159  fbc = state->getFermBC();
160  coeffs = coeffs_;
161 
162  // Sanity check
163  if (fbc.operator->() == 0) {
164  QDPIO::cerr << "QPhiXWilsonDslash: error: fbc is null" << std::endl;
165  QDP_abort(1);
166  }
167 
168  // Get the geometry:
169  QPhiX::QPhiXCLIArgs& QPhiXParams = TheQPhiXParams::Instance();
170 
171 
172 
173  if( theGeom == nullptr ) {
174 #ifdef DEBUG_QPHIX_DSLASH
175  QDPIO::cout << "Allocating Geometry" <<std::endl;
176  QDPIO::cout << " By="<< QPhiXParams.getBy() << std::endl;
177  QDPIO::cout << " Bz="<< QPhiXParams.getBz() << std::endl;
178  QDPIO::cout << " NCores="<< QPhiXParams.getNCores() << std::endl;
179  QDPIO::cout << " Sy="<< QPhiXParams.getSy() << std::endl;
180  QDPIO::cout << " Sz="<< QPhiXParams.getSz() << std::endl;
181  QDPIO::cout << " MinCt="<< QPhiXParams.getMinCt() << std::endl;
182 
183 #endif
184  theGeom = new Geom(Layout::subgridLattSize().slice(),
185  QPhiXParams.getBy(),
186  QPhiXParams.getBz(),
187  QPhiXParams.getNCores(),
188  QPhiXParams.getSy(),
189  QPhiXParams.getSz(),
190  0,0,QPhiXParams.getMinCt()); // Set Pads to zero explicitly
191 
192  if (theGeom == nullptr) {
193  QDPIO::cerr <<"Failed to allocate geometry. Aborting" <<std::endl;
194  QDP_abort(1);
195  }
196  }
197 
198  if( theDslash == nullptr ) {
199  double aniso_fac_s = toDouble(coeffs_[0]);
200  double aniso_fac_t = toDouble(coeffs_[Nd-1]);
201  double t_boundary = toDouble(1); // FBC will apply boundaries...
202 #ifdef DEBUG_QPHIX_DSLASH
203  QDPIO::cout << "Allocating Dslash: fac_s="<<aniso_fac_s<<" fac_t="<<aniso_fac_t << " t_boundary="<<t_boundary <<std::endl;
204 #endif
205  theDslash = new Dsl(theGeom,t_boundary,aniso_fac_s, aniso_fac_t);
206  if( theDslash == nullptr ) {
207  QDPIO::cerr << "Failed to allocate Dslash... Aborting " << std::endl;
208  QDP_abort(1);
209  }
210  }
211 
212  if( packed_gauge[0] == nullptr) {
213 #ifdef DEBUG_QPHIX_DSLASH
214  QDPIO::cout << "Allocating packed gauge field (cb=0)" << std::endl;
215 #endif
216 
217  packed_gauge[0] = (Gauge*)theGeom->allocCBGauge();
218  if( packed_gauge[0] == nullptr ) {
219  QDPIO::cerr << "Failed to allocate packed gauge_field(cb=0)" << std::endl;
220  QDP_abort(1);
221  }
222  }
223 
224  if( packed_gauge[1] == nullptr) {
225 #ifdef DEBUG_QPHIX_DSLASH
226  QDPIO::cout << "Allocating packed gauge field (cb=1)" << std::endl;
227 #endif
228  packed_gauge[1] = (Gauge*)theGeom->allocCBGauge();
229  if( packed_gauge[0] == nullptr ) {
230  QDPIO::cerr << "Failed to allocate packed gauge_field(cb=1)" << std::endl;
231  QDP_abort(1);
232  }
233  }
234 
235  const Q& u = state->getLinks();
236 #ifdef DEBUG_QPHIX_DSLASH
237  QDPIO::cout << "Packing Gauge Field" << std::endl;
238 #endif
239  QPhiX::qdp_pack_gauge<>(u,packed_gauge[0],packed_gauge[1],(*theGeom));
240  END_CODE();
241  }
242 
243  //! No real need for cleanup here
244  ~QPhiXWilsonDslash() {
245 
246 #ifndef CHROMA_STATIC_PACKED_GAUGE
247  // Keeping the packed gauges static shares them betwen objects which may be
248  // dangerous. SO this needs to be explicitly enabled, otherwise we free and reallocate
249  theGeom->free(packed_gauge[0]); packed_gauge[0] = nullptr;
250  theGeom->free(packed_gauge[1]); packed_gauge[1] = nullptr;
251 #endif
252 
253  // Never free these.
254  // delete theDslash; theDslash = nullptr;
255  // delete theGeom; theGeom = nullptr;
256  }
257 
258  /**
259  * Apply a dslash
260  *
261  * \param chi result (Write)
262  * \param psi source (Read)
263  * \param isign D'^dag or D' ( MINUS | PLUS ) resp. (Read)
264  * \param cb Checkerboard of OUTPUT std::vector (Read)
265  *
266  * \return The output of applying dslash on psi
267  */
268  void apply(T& chi, const T& psi,
269  enum PlusMinus isign, int cb) const
270  {
271  int source_cb = 1 - cb;
272  int target_cb = cb;
273  int qphix_isign = (isign == PLUS) ? +1 : -1;
274  int cbsize_in_blocks = rb[0].numSiteTable()/VecTraits<FT>::Soa;
275 
276  // Layout etc has been checked on construction and there is no padding
277  Spinor* chi_targ = (Spinor *)(chi.getFjit())+target_cb*cbsize_in_blocks;
278  Spinor* psi_src = (Spinor *)(psi.getFjit())+source_cb*cbsize_in_blocks;
279  theDslash->dslash(chi_targ,
280  psi_src,
281  packed_gauge[target_cb],
282  qphix_isign,
283  target_cb);
284 
285  // Apply Boundary
286  getFermBC().modifyF(chi, QDP::rb[cb]);
287  }
288 
289  //! Return the fermion BC object for this linear operator
290  const FermBC<T,P,Q>& getFermBC() const {return *fbc;}
291 
292  protected:
293  //! Get the anisotropy parameters
294  const multi1d<Real>& getCoeffs() const {return coeffs;}
295 
296  private:
297  multi1d<Real> coeffs; /*!< Nd array of coefficients of terms in the action */
298  Handle< FermBC<T,P,Q> > fbc;
299 
300 
301  // Pointers to held geom and dslash
302  static Geom *theGeom;
303  static Dsl *theDslash;
304 
305  // Pointers to packed gauge field
306 #ifdef CHROMA_STATIC_PACKED_GAUGE
307  static Gauge* packed_gauge[2];
308 #else
309  Gauge* packed_gauge[2];
310 #endif
311  };
312 
313 
314  // The Concrete Instances
315  using QPhiXWilsonDslashFloating = QPhiXWilsonDslash<LatticeFermion,multi1d<LatticeColorMatrix>,multi1d<LatticeColorMatrix>>;
316  using QPhiXWilsonDslashF = QPhiXWilsonDslash<LatticeFermionF,multi1d<LatticeColorMatrixF>,multi1d<LatticeColorMatrixF>>;
317  using QPhiXWilsonDslashD = QPhiXWilsonDslash<LatticeFermionD,multi1d<LatticeColorMatrixD>,multi1d<LatticeColorMatrixD>>;
318 
319 
320  QPhiXWilsonDslashF::Geom* QPhiXWilsonDslashF::theGeom = nullptr;
321  QPhiXWilsonDslashF::Dsl* QPhiXWilsonDslashF::theDslash = nullptr;
322 
323 #ifdef CHROMA_STATIC_PACKED_GAUGE
324  QPhiXWilsonDslashF::Gauge* QPhiXWilsonDslashF::packed_gauge[2] = { nullptr,nullptr };
325 #endif
326 
327  QPhiXWilsonDslashD::Geom* QPhiXWilsonDslashD::theGeom = nullptr;
328  QPhiXWilsonDslashD::Dsl* QPhiXWilsonDslashD::theDslash = nullptr;
329 
330 #ifdef CHROMA_STATIC_PACKED_GAUGE
331  QPhiXWilsonDslashD::Gauge* QPhiXWilsonDslashD::packed_gauge[2] = {nullptr,nullptr};
332 #endif
333 
334 } // End Namespace Chroma
335 
336 #endif // Ifdef BUILDING_CHROMA_QPHIX_DSLASH
337 #endif
Anisotropy parameters.
Wilson Dslash linear operator.
Nd
Definition: meslate.cc:74
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
static multi1d< LatticeColorMatrix > u
@ PLUS
Definition: chromabase.h:45
multi1d< LatticeFermion > chi(Ncb)
LatticeFermion psi
Definition: mespbg5p_w.cc:35
START_CODE()
int cb
Definition: invbicg.cc:120
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > state
Definition: pbg5p_w.cc:28
multi1d< Real > makeFermCoeffs(const AnisoParam_t &aniso)
Make fermion coefficients.
Definition: aniso_io.cc:63
Fermion action factories.
Support class for fermion actions and linear operators.
LatticeFermion T
Definition: t_clover.cc:11
multi1d< LatticeColorMatrix > Q
Definition: t_clover.cc:12