Bridge++  Ver.2.1.3
afopr_Domainwall_5din_eo.h
Go to the documentation of this file.
1 
10 #ifndef ACCEL_AFOPR_DOMAINWALL_5DIN_EO_INCLUDED
11 #define ACCEL_AFOPR_DOMAINWALL_5DIN_EO_INCLUDED
12 
13 #include <vector>
14 #include <string>
15 
16 #include "lib/Fopr/afopr.h"
20 #include "lib/IO/bridgeIO.h"
21 #include "lib/Tools/timer.h"
22 using Bridge::vout;
23 
25 
26 class Field;
27 
29 
40 template<typename AFIELD>
41 class AFopr_Domainwall_5din_eo : public AFopr<AFIELD>
42 {
43  public:
44  typedef typename AFIELD::real_t real_t;
45  static const std::string class_name;
46 
47  private:
48  // parameters common to overlap fermion
51  int m_Ns;
52  std::vector<int> m_boundary;
53  std::vector<real_t> m_b;
54  std::vector<real_t> m_c;
57  std::string m_kernel_type;
58  std::string m_repr;
59  std::string m_impl;
60 
61  std::vector<real_t> m_mat_inv;
62 
63  int m_Nx, m_Ny, m_Nz, m_Nt;
64  int m_Nvol, m_Ndim;
65  int m_Nx2, m_Nst2;
68 
70 
72 
74 
75  // for preconditioning
76  std::vector<real_t> m_dp;
77  std::vector<real_t> m_dpinv;
78  std::vector<real_t> m_dm;
79  std::vector<real_t> m_e;
80  std::vector<real_t> m_f;
82 
83  int do_comm[4];
85 
86  int m_Nsize[4]; // lattice sizes in units of SIMD variable
87  int m_bc[4];
88  int m_bc2[4];
89 
90  std::vector<int> m_Nbdsize;
92  std::vector<Channel> chsend_up, chrecv_up, chsend_dn, chrecv_dn;
94 
95  std::string m_mode;
96 
97  public:
100  : AFopr<AFIELD>()
101  { init(params); }
102 
105 
106  void setup_channels();
107 
108  void set_parameters(const Parameters& params);
109 
111  void set_parameters(const real_t mq, const real_t M0,
112  const int Ns, const std::vector<int> bc,
113  const real_t b, const real_t c,
114  const real_t alpha);
115 
116  void get_parameters(Parameters& params) const;
117 
119  void set_coefficients(const std::vector<real_t> b,
120  const std::vector<real_t> c);
121 
123  void set_precond_parameters();
124 
126  void set_matrix5d_inverse();
127 
129  bool needs_convert() { return true; }
130 
132  void convert(AFIELD&, const Field&);
133 
135  void reverse(Field&, const AFIELD&);
136 
137  void set_config(Field *U);
138 
139  void set_config_omp(Field *U);
140 
141  void set_config_impl(Field *U);
142 
143  void set_mode(std::string mode);
144 
145  std::string get_mode() const { return m_mode; }
146 
147  void mult(AFIELD& v, const AFIELD& w);
148 
149  void mult_dag(AFIELD& v, const AFIELD& w);
150 
151  void mult(AFIELD& v, const AFIELD& w, const std::string mode);
152 
153  void mult_dag(AFIELD& v, const AFIELD& w, std::string mode);
154 
155  void mult_gm5(AFIELD& v, const AFIELD& w);
156 
157  void DdagD(AFIELD&, const AFIELD&);
158  void D(AFIELD&, const AFIELD&);
159  void Ddag(AFIELD&, const AFIELD&);
160 
161  void DdagD_alt(AFIELD&, const AFIELD&);
162  void D_alt(AFIELD&, const AFIELD&);
163  void Ddag_alt(AFIELD&, const AFIELD&);
164 
165  void D_ee(AFIELD&, const AFIELD&, const int ieo);
166  void Ddag_ee(AFIELD&, const AFIELD&, const int ieo);
167 
168  void D_eo(AFIELD&, const AFIELD&, const int ieo);
169  void Ddag_eo(AFIELD&, const AFIELD&, const int ieo);
170 
171  void D_ee_inv(AFIELD&, const AFIELD&, const int ieo);
172  void Ddag_ee_inv(AFIELD&, const AFIELD&, const int ieo);
173 
174  void D_ee_inv_alt(AFIELD&, const AFIELD&, const int ieo);
175  void Ddag_ee_inv_alt(AFIELD&, const AFIELD&, const int ieo);
176 
177  void mult_gm5R(AFIELD&, const AFIELD&);
178  void mult_R(AFIELD&, const AFIELD&);
179 
180  // preconditioner
181  void LU_inv(AFIELD&, const AFIELD&);
182  void LUdag_inv(AFIELD&, const AFIELD&);
183 
184  int field_nin() { return m_NinF; }
185  int field_nvol() { return m_Nst2; }
186  int field_nex() { return 1; }
187 
189  double flop_count() { return flop_count(m_mode); }
190 
192  double flop_count(std::string mode);
193 
194  private:
196  void init(const Parameters& params);
197 
199  void tidyup();
200 
201  int mat_index(int ida, int isa, int idb, int isb){
202  return ida + m_Nd2 * isa + (m_Nd2 * m_Ns) * (idb + m_Nd2 * isb);
203  }
204 
205  unique_ptr<Timer> timer_pack;
206  unique_ptr<Timer> timer_bulk;
207  unique_ptr<Timer> timer_boundary;
208  unique_ptr<Timer> timer_comm;
209  unique_ptr<Timer> timer_comm_recv_wait;
210  unique_ptr<Timer> timer_comm_send_wait;
211  unique_ptr<Timer> timer_comm_send_start;
212  unique_ptr<Timer> timer_comm_recv_start;
213  unique_ptr<Timer> timer_mult_Deo;
214  unique_ptr<Timer> timer_mult_Dee_inv;
215 
216 #ifdef USE_FACTORY
217  private:
218  static AFopr<AFIELD> *create_object_with_params(const Parameters& params)
219  { return new AFopr_Domainwall_5din_eo(params); }
220 
221  public:
222  static bool register_factory()
223  {
225  "Domainwall_5din_eo", create_object_with_params);
226  return init1;
227  }
228 #endif
229 };
230 
231 #endif
AFopr_Domainwall_5din_eo::flop_count
double flop_count()
this returns the number of floating point number operations.
Definition: afopr_Domainwall_5din_eo.h:189
AFopr_Domainwall_5din_eo::Ddag_alt
void Ddag_alt(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:861
bridgeIO.h
AFopr_Domainwall_5din_eo::chrecv_dn
std::vector< Channel > chrecv_dn
Definition: afopr_Domainwall_5din_eo.h:92
AFopr_Domainwall_5din_eo::m_mode
std::string m_mode
Definition: afopr_Domainwall_5din_eo.h:95
AFopr_Domainwall_5din_eo::field_nvol
int field_nvol()
returns the volume of the fermion field.
Definition: afopr_Domainwall_5din_eo.h:185
AFopr_Domainwall_5din_eo::m_Nz
int m_Nz
Definition: afopr_Domainwall_5din_eo.h:63
AFopr_Domainwall_5din_eo::m_alpha
real_t m_alpha
parameter alpha
Definition: afopr_Domainwall_5din_eo.h:55
AFopr_Domainwall_5din_eo::init
void init(const Parameters &params)
initial setup.
Definition: afopr_Domainwall_5din_eo-tmpl.h:31
AFopr_Domainwall_5din_eo::m_vl
Bridge::VerboseLevel m_vl
verbose level
Definition: afopr_Domainwall_5din_eo.h:56
AFopr_Domainwall_5din_eo::m_bc
int m_bc[4]
Definition: afopr_Domainwall_5din_eo.h:87
AFopr
Definition: afopr.h:48
AFopr_Domainwall_5din_eo::m_v2
AFIELD m_v2
woking vectors
Definition: afopr_Domainwall_5din_eo.h:73
AFopr_Domainwall_5din_eo::set_matrix5d_inverse
void set_matrix5d_inverse()
set parameters for preconditioning.
Definition: afopr_Domainwall_5din_eo-tmpl.h:481
AFopr_Domainwall_5din_eo::timer_pack
unique_ptr< Timer > timer_pack
Definition: afopr_Domainwall_5din_eo.h:205
AFopr_Domainwall_5din_eo::field_nex
int field_nex()
returns the external degree of freedom of the fermion field.
Definition: afopr_Domainwall_5din_eo.h:186
communicator_impl.h
Parameters
Class for parameters.
Definition: parameters.h:46
AFopr_Domainwall_5din_eo::set_precond_parameters
void set_precond_parameters()
set parameters for preconditioning.
Definition: afopr_Domainwall_5din_eo-tmpl.h:440
AFopr_Domainwall_5din_eo::m_index_eo
AIndex_eo< real_t, AFIELD::IMPL > m_index_eo
Definition: afopr_Domainwall_5din_eo.h:69
AFopr_Domainwall_5din_eo::timer_comm_send_start
unique_ptr< Timer > timer_comm_send_start
Definition: afopr_Domainwall_5din_eo.h:211
AFopr_Domainwall_5din_eo::mult
void mult(AFIELD &v, const AFIELD &w)
multiplies fermion operator to a given field.
Definition: afopr_Domainwall_5din_eo-tmpl.h:634
AFopr_Domainwall_5din_eo::m_Ueo
AFIELD m_Ueo
copied gauge config. with boundary conditions.
Definition: afopr_Domainwall_5din_eo.h:71
AFopr_Domainwall_5din_eo::m_dm
std::vector< real_t > m_dm
Definition: afopr_Domainwall_5din_eo.h:78
AFopr_Domainwall_5din_eo::mult_dag
void mult_dag(AFIELD &v, const AFIELD &w)
hermitian conjugate of mult.
Definition: afopr_Domainwall_5din_eo-tmpl.h:674
AFopr_Domainwall_5din_eo::chset_recv
ChannelSet chset_recv
Definition: afopr_Domainwall_5din_eo.h:93
AFopr_Domainwall_5din_eo::mat_index
int mat_index(int ida, int isa, int idb, int isb)
Definition: afopr_Domainwall_5din_eo.h:201
AFopr_Domainwall_5din_eo::do_comm_any
int do_comm_any
communication switch (if any): (0: n, 1: y)
Definition: afopr_Domainwall_5din_eo.h:84
AFopr_Domainwall_5din_eo::m_mq
real_t m_mq
quark mass
Definition: afopr_Domainwall_5din_eo.h:49
AFopr_Domainwall_5din_eo::convert
void convert(AFIELD &, const Field &)
convert Field to AField for this class.
Definition: afopr_Domainwall_5din_eo-tmpl.h:555
AFopr_Domainwall_5din_eo::timer_comm
unique_ptr< Timer > timer_comm
Definition: afopr_Domainwall_5din_eo.h:208
AFopr_Domainwall_5din_eo::m_Nt
int m_Nt
Definition: afopr_Domainwall_5din_eo.h:63
AFopr_Domainwall_5din_eo::set_mode
void set_mode(std::string mode)
setting the mode of multiplication if necessary. Default implementation here is just to avoid irrelev...
Definition: afopr_Domainwall_5din_eo-tmpl.h:620
ChannelSet
ChannelSet class for a collection of channels.
Definition: channel.h:148
AFopr_Domainwall_5din_eo
Domain-wall fermion operator with even-odd site index.
Definition: afopr_Domainwall_5din_eo.h:41
aindex_eo.h
AFopr_Domainwall_5din_eo::reverse
void reverse(Field &, const AFIELD &)
reverse AField to Field.
Definition: afopr_Domainwall_5din_eo-tmpl.h:587
AFopr_Domainwall_5din_eo::timer_boundary
unique_ptr< Timer > timer_boundary
Definition: afopr_Domainwall_5din_eo.h:207
AFopr_Domainwall_5din_eo::m_bc2
int m_bc2[4]
Definition: afopr_Domainwall_5din_eo.h:88
AFopr_Domainwall_5din_eo::Ddag_ee_inv
void Ddag_ee_inv(AFIELD &, const AFIELD &, const int ieo)
Definition: afopr_Domainwall_5din_eo-tmpl.h:1330
AFopr_Domainwall_5din_eo::m_repr
std::string m_repr
Dirac matrix representation.
Definition: afopr_Domainwall_5din_eo.h:58
AFopr_Domainwall_5din_eo::mult_gm5R
void mult_gm5R(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:922
AFopr_Domainwall_5din_eo::m_kernel_type
std::string m_kernel_type
fermion kernel type
Definition: afopr_Domainwall_5din_eo.h:57
AFopr_Domainwall_5din_eo::Ddag
void Ddag(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:806
AFopr_Domainwall_5din_eo::m_b
std::vector< real_t > m_b
coefficient b (array)
Definition: afopr_Domainwall_5din_eo.h:53
AFopr_Domainwall_5din_eo::setup_channels
void setup_channels()
Definition: afopr_Domainwall_5din_eo-tmpl.h:194
Field::real_t
double real_t
Definition: field.h:51
AFopr_Domainwall_5din_eo::timer_mult_Deo
unique_ptr< Timer > timer_mult_Deo
Definition: afopr_Domainwall_5din_eo.h:213
AFopr_Domainwall_5din_eo::chrecv_up
std::vector< Channel > chrecv_up
Definition: afopr_Domainwall_5din_eo.h:92
AFopr_Domainwall_5din_eo::do_comm
int do_comm[4]
communication switch (4=Ndim): (0: n, 1: y)
Definition: afopr_Domainwall_5din_eo.h:83
AFopr_Domainwall_5din_eo::m_mat_inv
std::vector< real_t > m_mat_inv
5d matrix inverse
Definition: afopr_Domainwall_5din_eo.h:61
AFopr_Domainwall_5din_eo::set_coefficients
void set_coefficients(const std::vector< real_t > b, const std::vector< real_t > c)
set coefficients if they depend in s.
Definition: afopr_Domainwall_5din_eo-tmpl.h:409
AFopr_Domainwall_5din_eo::m_Ndim
int m_Ndim
Definition: afopr_Domainwall_5din_eo.h:64
AFopr_Domainwall_5din_eo::m_M0
real_t m_M0
domain-wall height
Definition: afopr_Domainwall_5din_eo.h:50
AFopr_Domainwall_5din_eo::m_Nx2
int m_Nx2
Definition: afopr_Domainwall_5din_eo.h:65
AFopr_Domainwall_5din_eo::AFopr_Domainwall_5din_eo
AFopr_Domainwall_5din_eo(const Parameters &params)
constructor.
Definition: afopr_Domainwall_5din_eo.h:99
AFopr_Domainwall_5din_eo::mult_gm5
void mult_gm5(AFIELD &v, const AFIELD &w)
multiplies gamma_5 matrix.
Definition: afopr_Domainwall_5din_eo-tmpl.h:881
AFopr_Domainwall_5din_eo::chset_send
ChannelSet chset_send
Definition: afopr_Domainwall_5din_eo.h:93
AFopr_Domainwall_5din_eo::Ddag_ee_inv_alt
void Ddag_ee_inv_alt(AFIELD &, const AFIELD &, const int ieo)
Definition: afopr_Domainwall_5din_eo-tmpl.h:1280
AFopr_Domainwall_5din_eo::D_ee_inv
void D_ee_inv(AFIELD &, const AFIELD &, const int ieo)
Definition: afopr_Domainwall_5din_eo-tmpl.h:1317
AFopr_Domainwall_5din_eo::m_e
std::vector< real_t > m_e
Definition: afopr_Domainwall_5din_eo.h:79
AFopr_Domainwall_5din_eo::m_NinF
int m_NinF
Definition: afopr_Domainwall_5din_eo.h:66
timer.h
AFopr_Domainwall_5din_eo::m_f
std::vector< real_t > m_f
Definition: afopr_Domainwall_5din_eo.h:80
AFopr_Domainwall_5din_eo::timer_comm_recv_start
unique_ptr< Timer > timer_comm_recv_start
Definition: afopr_Domainwall_5din_eo.h:212
AFopr_Domainwall_5din_eo::class_name
static const std::string class_name
Definition: afopr_Domainwall_5din_eo.h:45
AFopr_Domainwall_5din_eo::DdagD
void DdagD(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:771
AFopr_Domainwall_5din_eo::m_Nd
int m_Nd
Definition: afopr_Domainwall_5din_eo.h:66
AFopr_Domainwall_5din_eo::needs_convert
bool needs_convert()
this class needs convert of fermion field.
Definition: afopr_Domainwall_5din_eo.h:129
AFopr_Domainwall_5din_eo::get_mode
std::string get_mode() const
returns the current mult mode.
Definition: afopr_Domainwall_5din_eo.h:145
AFopr_Domainwall_5din_eo::m_Nd2
int m_Nd2
Definition: afopr_Domainwall_5din_eo.h:66
AFopr_Domainwall_5din_eo::m_Nst2
int m_Nst2
Definition: afopr_Domainwall_5din_eo.h:65
AFopr_Domainwall_5din_eo::m_Nvol
int m_Nvol
Definition: afopr_Domainwall_5din_eo.h:64
AFopr_Domainwall_5din_eo::timer_comm_send_wait
unique_ptr< Timer > timer_comm_send_wait
Definition: afopr_Domainwall_5din_eo.h:210
AFopr_Domainwall_5din_eo::Ddag_ee
void Ddag_ee(AFIELD &, const AFIELD &, const int ieo)
Definition: afopr_Domainwall_5din_eo-tmpl.h:1221
AFopr_Domainwall_5din_eo::tidyup
void tidyup()
final tidyup.
Definition: afopr_Domainwall_5din_eo-tmpl.h:151
AFopr_Domainwall_5din_eo::get_parameters
void get_parameters(Parameters &params) const
gets parameters by a Parameter object: to be implemented in a subclass.
Definition: afopr_Domainwall_5din_eo-tmpl.h:310
AFopr_Domainwall_5din_eo::m_dp
std::vector< real_t > m_dp
Definition: afopr_Domainwall_5din_eo.h:76
AFopr_Domainwall_5din_eo::~AFopr_Domainwall_5din_eo
~AFopr_Domainwall_5din_eo()
destructor.
Definition: afopr_Domainwall_5din_eo.h:104
AFopr_Domainwall_5din_eo::m_Ndf
int m_Ndf
Definition: afopr_Domainwall_5din_eo.h:66
AFopr_Domainwall_5din_eo::m_boundary
std::vector< int > m_boundary
boundary conditions
Definition: afopr_Domainwall_5din_eo.h:52
AFopr_Domainwall_5din_eo::m_dpinv
std::vector< real_t > m_dpinv
Definition: afopr_Domainwall_5din_eo.h:77
AFopr_Domainwall_5din_eo::m_Nbdsize
std::vector< int > m_Nbdsize
Definition: afopr_Domainwall_5din_eo.h:90
AFopr_Domainwall_5din_eo::set_parameters
void set_parameters(const Parameters &params)
sets parameters by a Parameter object: to be implemented in a subclass.
Definition: afopr_Domainwall_5din_eo-tmpl.h:246
AFopr_Domainwall_5din_eo::D_eo
void D_eo(AFIELD &, const AFIELD &, const int ieo)
Definition: afopr_Domainwall_5din_eo-tmpl.h:942
AFopr_Domainwall_5din_eo::m_Ny
int m_Ny
Definition: afopr_Domainwall_5din_eo.h:63
real_t
double real_t
Definition: bridgeACC_AField_double.cpp:14
AFopr_Domainwall_5din_eo::LU_inv
void LU_inv(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:1343
AFopr_Domainwall_5din_eo::m_Ieo_origin
int m_Ieo_origin
Definition: afopr_Domainwall_5din_eo.h:67
AFopr_Domainwall_5din_eo::mult_R
void mult_R(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:900
AFopr_Domainwall_5din_eo::set_config_impl
void set_config_impl(Field *U)
Definition: afopr_Domainwall_5din_eo-tmpl.h:544
AFopr_Domainwall_5din_eo::m_Nx
int m_Nx
Definition: afopr_Domainwall_5din_eo.h:63
AFopr_Domainwall_5din_eo::set_config
void set_config(Field *U)
sets the gauge configuration.
Definition: afopr_Domainwall_5din_eo-tmpl.h:514
AFopr_Domainwall_5din_eo::timer_mult_Dee_inv
unique_ptr< Timer > timer_mult_Dee_inv
Definition: afopr_Domainwall_5din_eo.h:214
AFopr_Domainwall_5din_eo::Ddag_eo
void Ddag_eo(AFIELD &, const AFIELD &, const int ieo)
Definition: afopr_Domainwall_5din_eo-tmpl.h:1069
AFopr_Domainwall_5din_eo::real_t
AFIELD::real_t real_t
Definition: afopr_Domainwall_5din_eo.h:44
AFopr_Domainwall_5din_eo::LUdag_inv
void LUdag_inv(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:1369
AFopr_Domainwall_5din_eo::m_c
std::vector< real_t > m_c
coefficient c (array)
Definition: afopr_Domainwall_5din_eo.h:54
AFopr_Domainwall_5din_eo::timer_bulk
unique_ptr< Timer > timer_bulk
Definition: afopr_Domainwall_5din_eo.h:206
AFopr_Domainwall_5din_eo::field_nin
int field_nin()
returns the on-site degree of freedom of the fermion field.
Definition: afopr_Domainwall_5din_eo.h:184
AFopr_Domainwall_5din_eo::m_impl
std::string m_impl
4d or 5d kernel implementation
Definition: afopr_Domainwall_5din_eo.h:59
AFopr_Domainwall_5din_eo::D_alt
void D_alt(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:847
AFopr_Domainwall_5din_eo::chsend_dn
std::vector< Channel > chsend_dn
Definition: afopr_Domainwall_5din_eo.h:92
AFopr_Domainwall_5din_eo::m_Nvcd
int m_Nvcd
Definition: afopr_Domainwall_5din_eo.h:66
AFopr_Domainwall_5din_eo::D_ee
void D_ee(AFIELD &, const AFIELD &, const int ieo)
Definition: afopr_Domainwall_5din_eo-tmpl.h:1199
AFopr_Domainwall_5din_eo::D
void D(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:793
AFopr_Domainwall_5din_eo::set_config_omp
void set_config_omp(Field *U)
Definition: afopr_Domainwall_5din_eo-tmpl.h:532
commonParameters.h
AFopr_Domainwall_5din_eo::chsend_up
std::vector< Channel > chsend_up
Definition: afopr_Domainwall_5din_eo.h:92
AFopr_Domainwall_5din_eo::DdagD_alt
void DdagD_alt(AFIELD &, const AFIELD &)
Definition: afopr_Domainwall_5din_eo-tmpl.h:826
AFopr_Domainwall_5din_eo::timer_comm_recv_wait
unique_ptr< Timer > timer_comm_recv_wait
Definition: afopr_Domainwall_5din_eo.h:209
Field
Container of Field-type object.
Definition: field.h:46
afopr.h
communicator.h
Bridge::VerboseLevel
VerboseLevel
Definition: bridgeIO.h:45
AFopr_Domainwall_5din_eo::m_g
real_t m_g
Definition: afopr_Domainwall_5din_eo.h:81
AFopr_Domainwall_5din_eo::m_Nsize
int m_Nsize[4]
Definition: afopr_Domainwall_5din_eo.h:86
AFopr_Domainwall_5din_eo::m_Ns
int m_Ns
size of fifth-dimension
Definition: afopr_Domainwall_5din_eo.h:51
AFopr_Domainwall_5din_eo::m_v1
AFIELD m_v1
Definition: afopr_Domainwall_5din_eo.h:73
Channel_impl
Definition: channel.h:86
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:572
AFopr_Domainwall_5din_eo::m_w1
AFIELD m_w1
Definition: afopr_Domainwall_5din_eo.h:73
AFopr_Domainwall_5din_eo::D_ee_inv_alt
void D_ee_inv_alt(AFIELD &, const AFIELD &, const int ieo)
Definition: afopr_Domainwall_5din_eo-tmpl.h:1243
AIndex_eo< real_t, AFIELD::IMPL >