QMCPACK
TwoBodyJastrow.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2021 QMCPACK developers.
6 //
7 // File developed by: Jeongnim Kim, jeongnim.kim@intel.com, Intel Corp.
8 // Amrita Mathuriya, amrita.mathuriya@intel.com, Intel Corp.
9 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@intel.com, Intel Corp.
12 //////////////////////////////////////////////////////////////////////////////////////
13 // -*- C++ -*-
14 
15 
16 #include "TwoBodyJastrow.h"
17 #include "CPU/SIMD/algorithm.hpp"
19 #include "ResourceCollection.h"
21 
22 namespace qmcplusplus
23 {
24 
25 template<typename T>
27 {
28  // fused buffer for fast transfer in mw_accept
30  // fused buffer for fast transfer in mw_ratioGrad
32  // fused buffer for fast transfer
34  // multi walker result
36  // multi walker result for V and G
38  /// memory pool for Uat, dUat, d2Uat [Nw][N_padded] + [Nw][DIM][N_padded] + [Nw][N_padded]
40  /// memory pool for cur_u, cur_du, cur_d2u [3][Nw][N_padded]. 3 is for value, first and second derivatives.
42 
43  TwoBodyJastrowMultiWalkerMem() : Resource("TwoBodyJastrowMultiWalkerMem") {}
44 
46 
47  std::unique_ptr<Resource> makeClone() const override { return std::make_unique<TwoBodyJastrowMultiWalkerMem>(*this); }
48 };
49 
50 template<typename FT>
52 {
53  collection.addResource(std::make_unique<TwoBodyJastrowMultiWalkerMem<RealType>>());
54 }
55 
56 template<typename FT>
58  const RefVectorWithLeader<WaveFunctionComponent>& wfc_list) const
59 {
60  auto& wfc_leader = wfc_list.getCastedLeader<TwoBodyJastrow<FT>>();
62  const size_t nw = wfc_list.size();
63  auto& mw_allUat = wfc_leader.mw_mem_handle_.getResource().mw_allUat;
64  mw_allUat.resize(N_padded * (DIM + 2) * nw);
65  for (size_t iw = 0; iw < nw; iw++)
66  {
67  // copy per walker Uat, dUat, d2Uat to shared buffer and attach buffer
68  auto& wfc = wfc_list.getCastedElement<TwoBodyJastrow<FT>>(iw);
69 
70  Vector<valT, aligned_allocator<valT>> Uat_view(mw_allUat.data() + iw * N_padded, N);
71  Uat_view = wfc.Uat;
72  wfc.Uat.free();
73  wfc.Uat.attachReference(mw_allUat.data() + iw * N_padded, N);
74 
75  VectorSoaContainer<valT, DIM, aligned_allocator<valT>> dUat_view(mw_allUat.data() + nw * N_padded +
76  iw * N_padded * DIM,
77  N, N_padded);
78  dUat_view = wfc.dUat;
79  wfc.dUat.free();
80  wfc.dUat.attachReference(N, N_padded, mw_allUat.data() + nw * N_padded + iw * N_padded * DIM);
81 
82  Vector<valT, aligned_allocator<valT>> d2Uat_view(mw_allUat.data() + nw * N_padded * (DIM + 1) + iw * N_padded, N);
83  d2Uat_view = wfc.d2Uat;
84  wfc.d2Uat.free();
85  wfc.d2Uat.attachReference(mw_allUat.data() + nw * N_padded * (DIM + 1) + iw * N_padded, N);
86  }
87  wfc_leader.mw_mem_handle_.getResource().mw_cur_allu.resize(N_padded * 3 * nw);
88 }
89 
90 template<typename FT>
92  const RefVectorWithLeader<WaveFunctionComponent>& wfc_list) const
93 {
94  auto& wfc_leader = wfc_list.getCastedLeader<TwoBodyJastrow<FT>>();
95  const size_t nw = wfc_list.size();
96  auto& mw_allUat = wfc_leader.mw_mem_handle_.getResource().mw_allUat;
97  for (size_t iw = 0; iw < nw; iw++)
98  {
99  // detach buffer and copy per walker Uat, dUat, d2Uat from shared buffer
100  auto& wfc = wfc_list.getCastedElement<TwoBodyJastrow<FT>>(iw);
101 
102  Vector<valT, aligned_allocator<valT>> Uat_view(mw_allUat.data() + iw * N_padded, N);
103  wfc.Uat.free();
104  wfc.Uat.resize(N);
105  wfc.Uat = Uat_view;
106 
107  VectorSoaContainer<valT, DIM, aligned_allocator<valT>> dUat_view(mw_allUat.data() + nw * N_padded +
108  iw * N_padded * DIM,
109  N, N_padded);
110  wfc.dUat.free();
111  wfc.dUat.resize(N);
112  wfc.dUat = dUat_view;
113 
114  Vector<valT, aligned_allocator<valT>> d2Uat_view(mw_allUat.data() + nw * N_padded * (DIM + 1) + iw * N_padded, N);
115  wfc.d2Uat.free();
116  wfc.d2Uat.resize(N);
117  wfc.d2Uat = d2Uat_view;
118  }
119  collection.takebackResource(wfc_leader.mw_mem_handle_);
120 }
121 
122 template<typename FT>
124 {
125  for (auto& [key, functor] : J2Unique)
126  opt_obj_refs.push_back(*functor);
127 }
128 
129 template<typename FT>
131 {
132  myVars.clear();
133  for (auto& [key, functor] : J2Unique)
134  {
135  functor->myVars.getIndex(active);
136  myVars.insertFrom(functor->myVars);
137  }
138  // Remove inactive variables so the mappings are correct
139  myVars.removeInactive();
140 
141  myVars.getIndex(active);
142 
143  const size_t NumVars = myVars.size();
144  if (NumVars)
145  {
146  OffSet.resize(F.size());
147 
148  // Find first active variable for the starting offset
149  int varoffset = -1;
150  for (int i = 0; i < myVars.size(); i++)
151  {
152  varoffset = myVars.Index[i];
153  if (varoffset != -1)
154  break;
155  }
156 
157  for (int i = 0; i < F.size(); ++i)
158  if (F[i] && F[i]->myVars.Index.size())
159  {
160  OffSet[i].first = F[i]->myVars.Index.front() - varoffset;
161  OffSet[i].second = F[i]->myVars.Index.size() + OffSet[i].first;
162  }
163  else
164  OffSet[i].first = OffSet[i].second = -1;
165  }
166 }
167 
168 template<typename FT>
169 void TwoBodyJastrow<FT>::evaluateRatios(const VirtualParticleSet& VP, std::vector<ValueType>& ratios)
170 {
171  for (int k = 0; k < ratios.size(); ++k)
172  ratios[k] =
173  std::exp(Uat[VP.refPtcl] - computeU(VP.getRefPS(), VP.refPtcl, VP.getDistTableAB(my_table_ID_).getDistRow(k)));
174 }
175 
176 template<typename FT>
179  std::vector<std::vector<ValueType>>& ratios) const
180 {
181  if (!use_offload_)
182  {
183  WaveFunctionComponent::mw_evaluateRatios(wfc_list, vp_list, ratios);
184  return;
185  }
186 
187  // add early return to prevent from accessing vp_list[0]
188  if (wfc_list.size() == 0)
189  return;
190  auto& wfc_leader = wfc_list.getCastedLeader<TwoBodyJastrow<FT>>();
191  auto& vp_leader = vp_list.getLeader();
192  const auto& mw_refPctls = vp_leader.getMultiWalkerRefPctls();
193  auto& mw_vals = wfc_leader.mw_mem_handle_.getResource().mw_vals;
194  const int nw = wfc_list.size();
195 
196  const size_t nVPs = mw_refPctls.size();
197  mw_vals.resize(nVPs);
198 
199  // need to access the spin group of refPtcl. vp_leader doesn't necessary be a member of the list.
200  // for this reason, refPtcl must be access from [0].
201  const int igt = vp_leader.getRefPS().getGroupID(vp_list[0].refPtcl);
202  const auto& dt_leader(vp_leader.getDistTableAB(wfc_leader.my_table_ID_));
203 
204  FT::mw_evaluateV(NumGroups, F.data() + igt * NumGroups, wfc_leader.N, grp_ids.data(), nVPs, mw_refPctls.data(),
205  dt_leader.getMultiWalkerDataPtr(), dt_leader.getPerTargetPctlStrideSize(), mw_vals.data(),
206  wfc_leader.mw_mem_handle_.getResource().transfer_buffer);
207 
208  size_t ivp = 0;
209  for (int iw = 0; iw < nw; ++iw)
210  {
211  const VirtualParticleSet& vp = vp_list[iw];
212  const auto& wfc = wfc_list.getCastedElement<TwoBodyJastrow<FT>>(iw);
213  for (int k = 0; k < vp.getTotalNum(); ++k, ivp++)
214  ratios[iw][k] = std::exp(wfc.Uat[mw_refPctls[ivp]] - mw_vals[ivp]);
215  }
216  assert(ivp == nVPs);
217 }
218 
219 template<typename FT>
221 {
222  if (Bytes_in_WFBuffer == 0)
223  {
224  Bytes_in_WFBuffer = buf.current();
225  buf.add(Uat.begin(), Uat.end());
226  buf.add(dUat.data(), dUat.end());
227  buf.add(d2Uat.begin(), d2Uat.end());
228  Bytes_in_WFBuffer = buf.current() - Bytes_in_WFBuffer;
229  // free local space
230  Uat.free();
231  dUat.free();
232  d2Uat.free();
233  }
234  else
235  {
236  buf.forward(Bytes_in_WFBuffer);
237  }
238 }
239 
240 template<typename FT>
242 {
243  Uat.attachReference(buf.lendReference<valT>(N), N);
244  dUat.attachReference(N, N_padded, buf.lendReference<valT>(N_padded * DIM));
245  d2Uat.attachReference(buf.lendReference<valT>(N), N);
246 }
247 
248 template<typename FT>
250  WFBufferType& buf,
251  bool fromscratch)
252 {
253  log_value_ = computeGL(P.G, P.L);
254  buf.forward(Bytes_in_WFBuffer);
255  return log_value_;
256 }
257 
258 template<typename FT>
260 {
261  valT curUat(0);
262  const int igt = P.GroupID[iat] * NumGroups;
263  for (int jg = 0; jg < NumGroups; ++jg)
264  if (F[igt + jg])
265  {
266  const FuncType& f2(*F[igt + jg]);
267  int iStart = P.first(jg);
268  int iEnd = P.last(jg);
269  curUat += f2.evaluateV(iat, iStart, iEnd, dist.data(), DistCompressed.data());
270  }
271  return curUat;
272 }
273 
274 template<typename FT>
275 typename TwoBodyJastrow<FT>::posT TwoBodyJastrow<FT>::accumulateG(const valT* restrict du, const DisplRow& displ) const
276 {
277  posT grad;
278  for (int idim = 0; idim < ndim; ++idim)
279  {
280  const valT* restrict dX = displ.data(idim);
281  valT s = valT();
282 
283 #pragma omp simd reduction(+ : s) aligned(du, dX : QMC_SIMD_ALIGNMENT)
284  for (int jat = 0; jat < N; ++jat)
285  s += du[jat] * dX[jat];
286  grad[idim] = s;
287  }
288  return grad;
289 }
290 
291 template<typename FT>
292 TwoBodyJastrow<FT>::TwoBodyJastrow(const std::string& obj_name, ParticleSet& p, bool use_offload)
293  : WaveFunctionComponent(obj_name),
294  N(p.getTotalNum()),
295  NumGroups(p.groups()),
296  ndim(p.getLattice().ndim),
297  lapfac(ndim - RealType(1)),
298  use_offload_(use_offload),
299  N_padded(getAlignedSize<valT>(N)),
300  my_table_ID_(p.addTable(p)),
301  j2_ke_corr_helper(p, F)
302 {
303  if (my_name_.empty())
304  throw std::runtime_error("TwoBodyJastrow object name cannot be empty!");
305 
306  F.resize(NumGroups * NumGroups, nullptr);
307 
308  // set up grp_ids
309  grp_ids.resize(N);
310  int count = 0;
311  for (int ig = 0; ig < NumGroups; ig++)
312  for (int j = p.first(ig); j < p.last(ig); j++)
313  grp_ids[count++] = ig;
314  assert(count == N);
315  grp_ids.updateTo();
316 
318 
319  KEcorr = 0.0;
320 }
321 
322 template<typename FT>
324 
325 template<typename FT>
327 {
328  if (std::any_of(F.begin(), F.end(), [](auto* ptr) { return ptr == nullptr; }))
329  app_warning() << "Two-body Jastrow \"" << my_name_ << "\" doesn't cover all the particle pairs. "
330  << "Consider fusing multiple entries if they are of the same type for optimal code performance."
331  << std::endl;
332 }
333 
334 template<typename FT>
336 {
337  Uat.resize(N);
338  dUat.resize(N);
339  d2Uat.resize(N);
340  // resize scratch compute
341  cur_u.resize(N);
342  cur_du.resize(N);
343  cur_d2u.resize(N);
344  old_u.resize(N);
345  old_du.resize(N);
346  old_d2u.resize(N);
347  DistCompressed.resize(N);
348  DistIndice.resize(N);
349 }
350 
351 template<typename FT>
352 void TwoBodyJastrow<FT>::addFunc(int ia, int ib, std::unique_ptr<FT> j)
353 {
354  assert(ia < NumGroups);
355  assert(ib < NumGroups);
356  if (ia == ib)
357  {
358  if (ia == 0) //first time, assign everything
359  {
360  int ij = 0;
361  for (int ig = 0; ig < NumGroups; ++ig)
362  for (int jg = 0; jg < NumGroups; ++jg, ++ij)
363  if (F[ij] == nullptr)
364  F[ij] = j.get();
365  }
366  else
367  F[ia * NumGroups + ib] = j.get();
368  }
369  else
370  {
371  // a very special case, 1 particle of each type (e.g. 1 up + 1 down)
372  // uu/dd/etc. was prevented by the builder
373  if (N == NumGroups)
374  for (int ig = 0; ig < NumGroups; ++ig)
375  F[ig * NumGroups + ig] = j.get();
376  // generic case
377  F[ia * NumGroups + ib] = j.get();
378  F[ib * NumGroups + ia] = j.get();
379  }
380  std::stringstream aname;
381  aname << ia << ib;
382  J2Unique[aname.str()] = std::move(j);
383 }
384 
385 template<typename FT>
386 std::unique_ptr<WaveFunctionComponent> TwoBodyJastrow<FT>::makeClone(ParticleSet& tqp) const
387 {
388  auto j2copy = std::make_unique<TwoBodyJastrow<FT>>(my_name_, tqp, use_offload_);
389  std::map<const FT*, FT*> fcmap;
390  for (int ig = 0; ig < NumGroups; ++ig)
391  for (int jg = ig; jg < NumGroups; ++jg)
392  {
393  int ij = ig * NumGroups + jg;
394  if (F[ij] == 0)
395  continue;
396  typename std::map<const FT*, FT*>::iterator fit = fcmap.find(F[ij]);
397  if (fit == fcmap.end())
398  {
399  auto fc = std::make_unique<FT>(*F[ij]);
400  fcmap[F[ij]] = fc.get();
401  j2copy->addFunc(ig, jg, std::move(fc));
402  }
403  }
404  j2copy->KEcorr = KEcorr;
405 
406  j2copy->myVars.clear();
407  j2copy->myVars.insertFrom(myVars);
408  j2copy->OffSet = OffSet;
409 
410  return j2copy;
411 }
412 
413 /** intenal function to compute \f$\sum_j u(r_j), du/dr, d2u/dr2\f$
414  * @param P particleset
415  * @param iat particle index
416  * @param dist starting distance
417  * @param u starting value
418  * @param du starting first deriv
419  * @param d2u starting second deriv
420  */
421 template<typename FT>
423  int iat,
424  const DistRow& dist,
425  RealType* restrict u,
426  RealType* restrict du,
427  RealType* restrict d2u,
428  bool triangle)
429 {
430  const int jelmax = triangle ? iat : N;
431  constexpr valT czero(0);
432  std::fill_n(u, jelmax, czero);
433  std::fill_n(du, jelmax, czero);
434  std::fill_n(d2u, jelmax, czero);
435 
436  const int igt = P.GroupID[iat] * NumGroups;
437  for (int jg = 0; jg < NumGroups; ++jg)
438  if (F[igt + jg])
439  {
440  const FuncType& f2(*F[igt + jg]);
441  int iStart = P.first(jg);
442  int iEnd = std::min(jelmax, P.last(jg));
443  f2.evaluateVGL(iat, iStart, iEnd, dist.data(), u, du, d2u, DistCompressed.data(), DistIndice.data());
444  }
445  //u[iat]=czero;
446  //du[iat]=czero;
447  //d2u[iat]=czero;
448 }
449 
450 template<typename FT>
452 {
453  //only ratio, ready to compute it again
454  UpdateMode = ORB_PBYP_RATIO;
455  cur_Uat = computeU(P, iat, P.getDistTableAA(my_table_ID_).getTempDists());
456  return std::exp(static_cast<PsiValue>(Uat[iat] - cur_Uat));
457 }
458 
459 template<typename FT>
461  const RefVectorWithLeader<ParticleSet>& p_list,
462  int iat,
463  std::vector<PsiValue>& ratios) const
464 {
465  if (!use_offload_)
466  {
467  WaveFunctionComponent::mw_calcRatio(wfc_list, p_list, iat, ratios);
468  return;
469  }
470 
471  //right now. Directly use FT::mw_evaluateVGL implementation.
472  assert(this == &wfc_list.getLeader());
473  auto& wfc_leader = wfc_list.getCastedLeader<TwoBodyJastrow<FT>>();
474  auto& p_leader = p_list.getLeader();
475  const auto& dt_leader = p_leader.getDistTableAA(my_table_ID_);
476  const int nw = wfc_list.size();
477 
478  auto& mw_vgl = wfc_leader.mw_mem_handle_.getResource().mw_vgl;
479  mw_vgl.resize(nw, DIM + 2);
480 
481  auto& mw_allUat = wfc_leader.mw_mem_handle_.getResource().mw_allUat;
482  auto& mw_cur_allu = wfc_leader.mw_mem_handle_.getResource().mw_cur_allu;
483 
484  FT::mw_evaluateVGL(iat, NumGroups, F.data() + p_leader.GroupID[iat] * NumGroups, wfc_leader.N, grp_ids.data(), nw,
485  mw_vgl.data(), N_padded, dt_leader.getMultiWalkerTempDataPtr(), mw_cur_allu.data(),
486  wfc_leader.mw_mem_handle_.getResource().mw_ratiograd_buffer);
487 
488  for (int iw = 0; iw < nw; iw++)
489  {
490  auto& wfc = wfc_list.getCastedElement<TwoBodyJastrow<FT>>(iw);
491  wfc.cur_Uat = mw_vgl[iw][0];
492  ratios[iw] = std::exp(static_cast<PsiValue>(wfc.Uat[iat] - wfc.cur_Uat));
493  }
494 }
495 
496 
497 template<typename FT>
498 void TwoBodyJastrow<FT>::evaluateRatiosAlltoOne(ParticleSet& P, std::vector<ValueType>& ratios)
499 {
500  const auto& d_table = P.getDistTableAA(my_table_ID_);
501  const auto& dist = d_table.getTempDists();
502 
503  for (int ig = 0; ig < NumGroups; ++ig)
504  {
505  const int igt = ig * NumGroups;
506  valT sumU(0);
507  for (int jg = 0; jg < NumGroups; ++jg)
508  if (F[igt + jg])
509  {
510  const FuncType& f2(*F[igt + jg]);
511  int iStart = P.first(jg);
512  int iEnd = P.last(jg);
513  sumU += f2.evaluateV(-1, iStart, iEnd, dist.data(), DistCompressed.data());
514  }
515 
516  for (int i = P.first(ig); i < P.last(ig); ++i)
517  {
518  // remove self-interaction
519  const valT Uself = F[igt + ig]->evaluate(dist[i]);
520  ratios[i] = std::exp(Uat[i] + Uself - sumU);
521  }
522  }
523 }
524 
525 template<typename FT>
527 {
528  return GradType(dUat[iat]);
529 }
530 
531 template<typename FT>
533 {
534  UpdateMode = ORB_PBYP_PARTIAL;
535 
536  computeU3(P, iat, P.getDistTableAA(my_table_ID_).getTempDists(), cur_u.data(), cur_du.data(), cur_d2u.data());
537  cur_Uat = simd::accumulate_n(cur_u.data(), N, valT());
538  DiffVal = Uat[iat] - cur_Uat;
539  grad_iat += accumulateG(cur_du.data(), P.getDistTableAA(my_table_ID_).getTempDispls());
540  return std::exp(static_cast<PsiValue>(DiffVal));
541 }
542 
543 template<typename FT>
545  const RefVectorWithLeader<ParticleSet>& p_list,
546  int iat,
547  std::vector<PsiValue>& ratios,
548  std::vector<GradType>& grad_new) const
549 {
550  if (!use_offload_)
551  {
552  WaveFunctionComponent::mw_ratioGrad(wfc_list, p_list, iat, ratios, grad_new);
553  return;
554  }
555 
556  assert(this == &wfc_list.getLeader());
557  auto& wfc_leader = wfc_list.getCastedLeader<TwoBodyJastrow<FT>>();
558  auto& p_leader = p_list.getLeader();
559  const auto& dt_leader = p_leader.getDistTableAA(my_table_ID_);
560  const int nw = wfc_list.size();
561 
562  auto& mw_vgl = wfc_leader.mw_mem_handle_.getResource().mw_vgl;
563  mw_vgl.resize(nw, DIM + 2);
564 
565  auto& mw_allUat = wfc_leader.mw_mem_handle_.getResource().mw_allUat;
566  auto& mw_cur_allu = wfc_leader.mw_mem_handle_.getResource().mw_cur_allu;
567 
568  FT::mw_evaluateVGL(iat, NumGroups, F.data() + p_leader.GroupID[iat] * NumGroups, wfc_leader.N, grp_ids.data(), nw,
569  mw_vgl.data(), N_padded, dt_leader.getMultiWalkerTempDataPtr(), mw_cur_allu.data(),
570  wfc_leader.mw_mem_handle_.getResource().mw_ratiograd_buffer);
571 
572  for (int iw = 0; iw < nw; iw++)
573  {
574  auto& wfc = wfc_list.getCastedElement<TwoBodyJastrow<FT>>(iw);
575  wfc.cur_Uat = mw_vgl[iw][0];
576  ratios[iw] = std::exp(static_cast<PsiValue>(wfc.Uat[iat] - wfc.cur_Uat));
577  for (int idim = 0; idim < ndim; idim++)
578  grad_new[iw][idim] += mw_vgl[iw][idim + 1];
579  }
580 }
581 
582 template<typename FT>
583 void TwoBodyJastrow<FT>::acceptMove(ParticleSet& P, int iat, bool safe_to_delay)
584 {
585  // get the old u, du, d2u
586  const auto& d_table = P.getDistTableAA(my_table_ID_);
587  computeU3(P, iat, d_table.getOldDists(), old_u.data(), old_du.data(), old_d2u.data());
588  if (UpdateMode == ORB_PBYP_RATIO)
589  { //ratio-only during the move; need to compute derivatives
590  const auto& dist = d_table.getTempDists();
591  computeU3(P, iat, dist, cur_u.data(), cur_du.data(), cur_d2u.data());
592  }
593 
594  valT cur_d2Uat(0);
595  const auto& new_dr = d_table.getTempDispls();
596  const auto& old_dr = d_table.getOldDispls();
597 #pragma omp simd reduction(+ : cur_d2Uat)
598  for (int jat = 0; jat < N; jat++)
599  {
600  const valT du = cur_u[jat] - old_u[jat];
601  const valT newl = cur_d2u[jat] + lapfac * cur_du[jat];
602  const valT dl = old_d2u[jat] + lapfac * old_du[jat] - newl;
603  Uat[jat] += du;
604  d2Uat[jat] += dl;
605  cur_d2Uat -= newl;
606  }
607  posT cur_dUat;
608  for (int idim = 0; idim < ndim; ++idim)
609  {
610  const valT* restrict new_dX = new_dr.data(idim);
611  const valT* restrict old_dX = old_dr.data(idim);
612  const valT* restrict cur_du_pt = cur_du.data();
613  const valT* restrict old_du_pt = old_du.data();
614  valT* restrict save_g = dUat.data(idim);
615  valT cur_g = cur_dUat[idim];
616 #pragma omp simd reduction(+ : cur_g) aligned(old_dX, new_dX, save_g, cur_du_pt, old_du_pt : QMC_SIMD_ALIGNMENT)
617  for (int jat = 0; jat < N; jat++)
618  {
619  const valT newg = cur_du_pt[jat] * new_dX[jat];
620  const valT dg = newg - old_du_pt[jat] * old_dX[jat];
621  save_g[jat] -= dg;
622  cur_g += newg;
623  }
624  cur_dUat[idim] = cur_g;
625  }
626  log_value_ += Uat[iat] - cur_Uat;
627  Uat[iat] = cur_Uat;
628  dUat(iat) = cur_dUat;
629  d2Uat[iat] = cur_d2Uat;
630 }
631 
632 template<typename FT>
634  const RefVectorWithLeader<ParticleSet>& p_list,
635  int iat,
636  const std::vector<bool>& isAccepted,
637  bool safe_to_delay) const
638 {
639  if (!use_offload_)
640  {
641  WaveFunctionComponent::mw_accept_rejectMove(wfc_list, p_list, iat, isAccepted, safe_to_delay);
642  return;
643  }
644 
645  assert(this == &wfc_list.getLeader());
646  auto& wfc_leader = wfc_list.getCastedLeader<TwoBodyJastrow<FT>>();
647  auto& p_leader = p_list.getLeader();
648  const auto& dt_leader = p_leader.getDistTableAA(my_table_ID_);
649  const int nw = wfc_list.size();
650 
651  auto& mw_vgl = wfc_leader.mw_mem_handle_.getResource().mw_vgl;
652 
653  auto& mw_allUat = wfc_leader.mw_mem_handle_.getResource().mw_allUat;
654  auto& mw_cur_allu = wfc_leader.mw_mem_handle_.getResource().mw_cur_allu;
655 
656  for (int iw = 0; iw < nw; iw++)
657  {
658  auto& wfc = wfc_list.getCastedElement<TwoBodyJastrow<FT>>(iw);
659  wfc.log_value_ += wfc.Uat[iat] - mw_vgl[iw][0];
660  }
661 
662  // this call may go asynchronous, then need to wait at mw_calcRatio mw_ratioGrad and mw_completeUpdates
663  FT::mw_updateVGL(iat, isAccepted, NumGroups, F.data() + p_leader.GroupID[iat] * NumGroups, wfc_leader.N,
664  grp_ids.data(), nw, mw_vgl.data(), N_padded, dt_leader.getMultiWalkerTempDataPtr(), mw_allUat.data(),
665  mw_cur_allu.data(), wfc_leader.mw_mem_handle_.getResource().mw_update_buffer);
666 }
667 
668 template<typename FT>
670 {
671  const auto& d_table = P.getDistTableAA(my_table_ID_);
672  for (int ig = 0; ig < NumGroups; ++ig)
673  {
674  for (int iat = P.first(ig), last = P.last(ig); iat < last; ++iat)
675  {
676  computeU3(P, iat, d_table.getDistRow(iat), cur_u.data(), cur_du.data(), cur_d2u.data(), true);
677  Uat[iat] = simd::accumulate_n(cur_u.data(), iat, valT());
678  posT grad;
679  valT lap(0);
680  const valT* restrict u = cur_u.data();
681  const valT* restrict du = cur_du.data();
682  const valT* restrict d2u = cur_d2u.data();
683  const auto& displ = d_table.getDisplRow(iat);
684 #pragma omp simd reduction(+ : lap) aligned(du, d2u : QMC_SIMD_ALIGNMENT)
685  for (int jat = 0; jat < iat; ++jat)
686  lap += d2u[jat] + lapfac * du[jat];
687  for (int idim = 0; idim < ndim; ++idim)
688  {
689  const valT* restrict dX = displ.data(idim);
690  valT s = valT();
691 #pragma omp simd reduction(+ : s) aligned(du, dX : QMC_SIMD_ALIGNMENT)
692  for (int jat = 0; jat < iat; ++jat)
693  s += du[jat] * dX[jat];
694  grad[idim] = s;
695  }
696  dUat(iat) = grad;
697  d2Uat[iat] = -lap;
698 // add the contribution from the upper triangle
699 #pragma omp simd aligned(u, du, d2u : QMC_SIMD_ALIGNMENT)
700  for (int jat = 0; jat < iat; jat++)
701  {
702  Uat[jat] += u[jat];
703  d2Uat[jat] -= d2u[jat] + lapfac * du[jat];
704  }
705  for (int idim = 0; idim < ndim; ++idim)
706  {
707  valT* restrict save_g = dUat.data(idim);
708  const valT* restrict dX = displ.data(idim);
709 #pragma omp simd aligned(save_g, du, dX : QMC_SIMD_ALIGNMENT)
710  for (int jat = 0; jat < iat; jat++)
711  save_g[jat] -= du[jat] * dX[jat];
712  }
713  }
714  }
715 }
716 
717 template<typename FT>
719  const RefVectorWithLeader<ParticleSet>& p_list,
720  const std::vector<bool>& recompute) const
721 {
722  if (!use_offload_)
723  {
724  WaveFunctionComponent::mw_recompute(wfc_list, p_list, recompute);
725  return;
726  }
727 
728  auto& wfc_leader = wfc_list.getCastedLeader<TwoBodyJastrow<FT>>();
729  assert(this == &wfc_leader);
730  for (int iw = 0; iw < wfc_list.size(); iw++)
731  if (recompute[iw])
732  wfc_list[iw].recompute(p_list[iw]);
733  wfc_leader.mw_mem_handle_.getResource().mw_allUat.updateTo();
734 }
735 
736 template<typename FT>
740 {
741  recompute(P);
742  return log_value_ = computeGL(G, L);
743 }
744 
745 template<typename FT>
747  const RefVectorWithLeader<ParticleSet>& p_list,
749  const RefVector<ParticleSet::ParticleLaplacian>& L_list) const
750 
751 {
752  if (!use_offload_)
753  {
754  WaveFunctionComponent::mw_evaluateLog(wfc_list, p_list, G_list, L_list);
755  return;
756  }
757 
758  assert(this == &wfc_list.getLeader());
759  const std::vector<bool> recompute_all(wfc_list.size(), true);
760  mw_recompute(wfc_list, p_list, recompute_all);
761 
762  for (int iw = 0; iw < wfc_list.size(); iw++)
763  {
764  auto& wfc = wfc_list.getCastedElement<TwoBodyJastrow<FT>>(iw);
765  wfc.log_value_ = wfc.computeGL(G_list[iw], L_list[iw]);
766  }
767 }
768 
769 
770 template<typename FT>
773 {
774  for (int iat = 0; iat < N; ++iat)
775  {
776  G[iat] += dUat[iat];
777  L[iat] += d2Uat[iat];
778  }
779  return -0.5 * simd::accumulate_n(Uat.data(), N, QTFull::RealType());
780 }
781 
782 template<typename FT>
786  bool fromscratch)
787 {
788  return log_value_ = computeGL(G, L);
789 }
790 
791 template<typename FT>
793  const RefVectorWithLeader<ParticleSet>& p_list,
796  bool fromscratch) const
797 {
798  if (!use_offload_)
799  {
800  WaveFunctionComponent::mw_evaluateGL(wfc_list, p_list, G_list, L_list, fromscratch);
801  return;
802  }
803 
804  assert(this == &wfc_list.getLeader());
805  for (int iw = 0; iw < wfc_list.size(); iw++)
806  {
807  auto& wfc = wfc_list.getCastedElement<TwoBodyJastrow<FT>>(iw);
808  wfc.log_value_ = wfc.computeGL(G_list[iw], L_list[iw]);
809  }
810 }
811 
812 template<typename FT>
814 {
815  if (ndim < 3)
816  throw std::runtime_error("double check! See 2d jastrow test.");
817  log_value_ = 0.0;
818  const auto& d_ee(P.getDistTableAA(my_table_ID_));
819  valT dudr, d2udr2;
820 
821  Tensor<valT, DIM> ident;
822  grad_grad_psi = 0.0;
823  ident.diagonal(1.0);
824 
825  for (int i = 1; i < N; ++i)
826  {
827  const auto& dist = d_ee.getDistRow(i);
828  const auto& displ = d_ee.getDisplRow(i);
829  auto ig = P.GroupID[i];
830  const int igt = ig * NumGroups;
831  for (int j = 0; j < i; ++j)
832  {
833  auto r = dist[j];
834  auto rinv = 1.0 / r;
835  auto dr = displ[j];
836  auto jg = P.GroupID[j];
837  auto uij = F[igt + jg]->evaluate(r, dudr, d2udr2);
838  log_value_ -= uij;
839  auto hess = rinv * rinv * outerProduct(dr, dr) * (d2udr2 - dudr * rinv) + ident * dudr * rinv;
840  grad_grad_psi[i] -= hess;
841  grad_grad_psi[j] -= hess;
842  }
843  }
844 }
845 
846 template<typename FT>
848  const opt_variables_type& active,
849  Vector<ValueType>& dlogpsi,
850  Vector<ValueType>& dhpsioverpsi)
851 {
852  if (myVars.size() == 0)
853  return;
854 
855  evaluateDerivativesWF(P, active, dlogpsi);
856  bool recalculate(false);
857  std::vector<bool> rcsingles(myVars.size(), false);
858  for (int k = 0; k < myVars.size(); ++k)
859  {
860  int kk = myVars.where(k);
861  if (kk < 0)
862  continue;
863  if (active.recompute(kk))
864  recalculate = true;
865  rcsingles[k] = true;
866  }
867  if (recalculate)
868  {
869  for (int k = 0; k < myVars.size(); ++k)
870  {
871  int kk = myVars.where(k);
872  if (kk < 0)
873  continue;
874  if (rcsingles[k])
875  {
876  dhpsioverpsi[kk] = -RealType(0.5) * ValueType(Sum(lapLogPsi[k])) - ValueType(Dot(P.G, gradLogPsi[k]));
877  }
878  }
879  }
880 }
881 
882 template<typename FT>
884  const opt_variables_type& active,
885  Vector<ValueType>& dlogpsi)
886 {
887  if (myVars.size() == 0)
888  return;
889 
890  resizeWFOptVectors();
891 
892  bool recalculate(false);
893  std::vector<bool> rcsingles(myVars.size(), false);
894  for (int k = 0; k < myVars.size(); ++k)
895  {
896  int kk = myVars.where(k);
897  if (kk < 0)
898  continue;
899  if (active.recompute(kk))
900  recalculate = true;
901  rcsingles[k] = true;
902  }
903  if (recalculate)
904  {
905  ///precomputed recalculation switch
906  std::vector<bool> RecalcSwitch(F.size(), false);
907  for (int i = 0; i < F.size(); ++i)
908  {
909  if (OffSet[i].first < 0)
910  {
911  // nothing to optimize
912  RecalcSwitch[i] = false;
913  }
914  else
915  {
916  bool recalcFunc(false);
917  for (int rcs = OffSet[i].first; rcs < OffSet[i].second; rcs++)
918  if (rcsingles[rcs] == true)
919  recalcFunc = true;
920  RecalcSwitch[i] = recalcFunc;
921  }
922  }
923  dLogPsi = 0.0;
924  const size_t NumVars = myVars.size();
925  for (int p = 0; p < NumVars; ++p)
926  {
927  gradLogPsi[p] = 0.0;
928  lapLogPsi[p] = 0.0;
929  }
930  std::vector<TinyVector<RealType, 3>> derivs(NumVars);
931  const auto& d_table = P.getDistTableAA(my_table_ID_);
932  constexpr RealType cone(1);
933  const size_t n = d_table.sources();
934  const size_t ng = P.groups();
935  for (size_t i = 1; i < n; ++i)
936  {
937  const size_t ig = P.GroupID[i] * ng;
938  const auto& dist = d_table.getDistRow(i);
939  const auto& displ = d_table.getDisplRow(i);
940  for (size_t j = 0; j < i; ++j)
941  {
942  const size_t ptype = ig + P.GroupID[j];
943  if (RecalcSwitch[ptype])
944  {
945  std::fill(derivs.begin(), derivs.end(), 0.0);
946  if (!F[ptype]->evaluateDerivatives(dist[j], derivs))
947  continue;
948  RealType rinv(cone / dist[j]);
949  PosType dr(displ[j]);
950  if (ndim < 3)
951  dr[2] = 0;
952  for (int p = OffSet[ptype].first, ip = 0; p < OffSet[ptype].second; ++p, ++ip)
953  {
954  RealType dudr(rinv * derivs[ip][1]);
955  RealType lap(derivs[ip][2] + lapfac * dudr);
956  PosType gr(dudr * dr);
957  dLogPsi[p] -= derivs[ip][0];
958  gradLogPsi[p][i] += gr;
959  gradLogPsi[p][j] -= gr;
960  lapLogPsi[p][i] -= lap;
961  lapLogPsi[p][j] -= lap;
962  }
963  }
964  }
965  }
966  for (int k = 0; k < myVars.size(); ++k)
967  {
968  int kk = myVars.where(k);
969  if (kk < 0)
970  continue;
971  if (rcsingles[k])
972  {
973  dlogpsi[kk] = dLogPsi[k];
974  }
975  //optVars.setDeriv(p,dLogPsi[ip],-0.5*Sum(lapLogPsi[ip])-Dot(P.G,gradLogPsi[ip]));
976  }
977  }
978 }
979 
980 template<typename FT>
982  const opt_variables_type& optvars,
983  std::vector<ValueType>& ratios,
984  Matrix<ValueType>& dratios)
985 {
986  evaluateRatios(VP, ratios);
987  if (myVars.size() == 0)
988  return;
989 
990  bool recalculate(false);
991  std::vector<bool> rcsingles(myVars.size(), false);
992  for (int k = 0; k < myVars.size(); ++k)
993  {
994  int kk = myVars.where(k);
995  if (kk < 0)
996  continue;
997  if (optvars.recompute(kk))
998  recalculate = true;
999  rcsingles[k] = true;
1000  }
1001 
1002  if (recalculate)
1003  {
1004  ///precomputed recalculation switch
1005  std::vector<bool> RecalcSwitch(F.size(), false);
1006  for (int i = 0; i < F.size(); ++i)
1007  {
1008  if (OffSet[i].first < 0)
1009  {
1010  // nothing to optimize
1011  RecalcSwitch[i] = false;
1012  }
1013  else
1014  {
1015  bool recalcFunc(false);
1016  for (int rcs = OffSet[i].first; rcs < OffSet[i].second; rcs++)
1017  if (rcsingles[rcs] == true)
1018  recalcFunc = true;
1019  RecalcSwitch[i] = recalcFunc;
1020  }
1021  }
1022  const size_t NumVars = myVars.size();
1023  std::vector<RealType> derivs_ref(NumVars);
1024  std::vector<RealType> derivs(NumVars);
1025  const auto& d_table = VP.getDistTableAB(my_table_ID_);
1026  const size_t n = d_table.sources();
1027  const size_t nt = VP.getTotalNum();
1028  for (size_t i = 0; i < n; ++i)
1029  {
1030  if (i == VP.refPtcl)
1031  continue;
1032  const size_t ptype = VP.getRefPS().GroupID[i] * VP.getRefPS().groups() + VP.getRefPS().GroupID[VP.refPtcl];
1033  if (!RecalcSwitch[ptype])
1034  continue;
1035  const auto dist_ref = i < VP.refPtcl ? VP.getRefPS().getDistTableAA(my_table_ID_).getDistRow(VP.refPtcl)[i]
1036  : VP.getRefPS().getDistTableAA(my_table_ID_).getDistRow(i)[VP.refPtcl];
1037  //first calculate the old derivatives VP.refPtcl.
1038  std::fill(derivs_ref.begin(), derivs_ref.end(), 0.0);
1039  F[ptype]->evaluateDerivatives(dist_ref, derivs_ref);
1040  for (size_t j = 0; j < nt; ++j)
1041  {
1042  std::fill(derivs.begin(), derivs.end(), 0.0);
1043  F[ptype]->evaluateDerivatives(d_table.getDistRow(j)[i], derivs);
1044  for (int ip = 0, p = F[ptype]->myVars.Index.front(); ip < F[ptype]->myVars.Index.size(); ++ip, ++p)
1045  dratios[j][p] += derivs_ref[ip] - derivs[ip];
1046  }
1047  }
1048  }
1049 }
1050 
1055 } // namespace qmcplusplus
void checkSanity() const override
Validate the internal consistency of the object.
T2 accumulate_n(const T1 *restrict in, size_t n, T2 res)
Definition: algorithm.hpp:26
T Sum(const ParticleAttrib< T > &pa)
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
bool recompute(int i) const
Definition: VariableSet.h:206
size_t addResource(std::unique_ptr< Resource > &&res, bool noprint=false)
size_t getAlignedSize(size_t n)
return size in T&#39;s of allocated aligned memory
std::ostream & app_warning()
Definition: OutputManager.h:69
void takebackResource(ResourceHandle< RS > &res_handle)
const std::string my_name_
Name of the object It is required to be different for objects of the same derived type like multiple ...
const ParticleSet & getRefPS() const
ParticleSet this object refers to.
void mw_evaluateLog(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, const RefVector< ParticleSet::ParticleGradient > &G_list, const RefVector< ParticleSet::ParticleLaplacian > &L_list) const override
evaluate from scratch the same type WaveFunctionComponent of multiple walkers
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void registerData(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
const DistanceTableAA & getDistTableAA(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAA
virtual void mw_recompute(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, const std::vector< bool > &recompute) const
std::unique_ptr< Resource > makeClone() const override
const DistRow & getDistRow(int iel) const
return a row of distances for a given target particle
void forward(size_type n)
Definition: PooledMemory.h:162
void addFunc(int ia, int ib, std::unique_ptr< FT > j)
add functor for (ia,ib) pair
void fill_n(T *x, size_t count, const T &value)
Definition: OMPstd.hpp:21
constexpr std::complex< float > czero
Definition: BLAS.hpp:51
Vector< char, OffloadPinnedAllocator< char > > mw_update_buffer
constexpr std::complex< float > cone
Definition: BLAS.hpp:50
A ParticleSet that handles virtual moves of a selected particle of a given physical ParticleSet Virtu...
GradType evalGrad(ParticleSet &P, int iat) override
return the current gradient for the iat-th particle
int refPtcl
Reference particle.
LatticeGaussianProduct::GradType GradType
SoA adaptor class for Vector<TinyVector<T,D> >
void extractOptimizableObjectRefs(UniqueOptObjRefs &opt_obj_refs) override
extract underlying OptimizableObject references
int first(int igroup) const
return the first index of a group i
Definition: ParticleSet.h:514
void free()
free
Definition: OhmmsVector.h:196
const DisplRow & getTempDispls() const
return the temporary displacements when a move is proposed
std::unique_ptr< WaveFunctionComponent > makeClone(ParticleSet &tqp) const override
make clone
Attaches a unit to a Vector for IO.
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
PsiValue ratioGrad(ParticleSet &P, int iat, GradType &grad_iat) override
evaluate the ratio of the new to old WaveFunctionComponent value and the new gradient ...
const DistRow & getTempDists() const
return the temporary distances when a move is proposed
void resizeInternalStorage()
initialize storage Uat,dUat, d2Uat
T Dot(const ParticleAttrib< TinyVector< T, D >> &pa, const ParticleAttrib< TinyVector< T, D >> &pb)
T min(T a, T b)
void releaseResource(ResourceCollection &collection, const RefVectorWithLeader< WaveFunctionComponent > &wfc_list) const override
return a shared resource to a collection
ParticleIndex GroupID
Species ID.
Definition: ParticleSet.h:77
virtual void mw_evaluateGL(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, const RefVector< ParticleSet::ParticleGradient > &G_list, const RefVector< ParticleSet::ParticleLaplacian > &L_list, bool fromscratch) const
evaluate gradients and laplacian of the same type WaveFunctionComponent of multiple walkers ...
std::vector< FT * > F
Container for . treat every pointer as a reference.
std::complex< QTFull::RealType > LogValue
void evaluateDerivativesWF(ParticleSet &P, const opt_variables_type &active, Vector< ValueType > &dlogpsi) override
const DistanceTableAB & getDistTableAB(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAB
QTFull::RealType computeGL(ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) const
compute G and L from internally stored data
int groups() const
return the number of groups
Definition: ParticleSet.h:511
An abstract class for a component of a many-body trial wave function.
posT accumulateG(const valT *restrict du, const DisplRow &displ) const
compute gradient
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
TwoBodyJastrow(const std::string &obj_name, ParticleSet &p, bool use_offload)
Vector< char, OffloadPinnedAllocator< char > > transfer_buffer
void recompute(const ParticleSet &P) override
recompute internal data assuming distance table is fully ready
void mw_evaluateRatios(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< const VirtualParticleSet > &vp_list, std::vector< std::vector< ValueType >> &ratios) const override
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
Matrix< T, OffloadPinnedAllocator< T > > mw_vgl
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > outerProduct(const TinyVector< T1, D > &lhs, const TinyVector< T2, D > &rhs)
Definition: TinyVector.h:211
LogValue updateBuffer(ParticleSet &P, WFBufferType &buf, bool fromscratch=false) override
For particle-by-particle move.
void createResource(ResourceCollection &collection) const override
initialize a shared resource and hand it to a collection
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
CASTTYPE & getCastedElement(size_t i) const
ResourceHandle< TwoBodyJastrowMultiWalkerMem< RealType > > mw_mem_handle_
valT computeU(const ParticleSet &P, int iat, const DistRow &dist)
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
void mw_evaluateGL(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, const RefVector< ParticleSet::ParticleGradient > &G_list, const RefVector< ParticleSet::ParticleLaplacian > &L_list, bool fromscratch) const override
evaluate gradients and laplacian of the same type WaveFunctionComponent of multiple walkers ...
Vector< char, OffloadPinnedAllocator< char > > mw_ratiograd_buffer
int last(int igroup) const
return the last index of a group i
Definition: ParticleSet.h:517
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
const DistRow & getDistRow(int iel) const
return a row of distances for a given target particle
typename FT::real_type valT
type of each component U, dU, d2U;
PsiValue ratio(ParticleSet &P, int iat) override
evaluate the ratio of the new to old WaveFunctionComponent value
void evaluateDerivRatios(const VirtualParticleSet &VP, const opt_variables_type &optvars, std::vector< ValueType > &ratios, Matrix< ValueType > &dratios) override
Specialization for two-body Jastrow function using multiple functors.
void mw_ratioGrad(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< PsiValue > &ratios, std::vector< GradType > &grad_new) const override
void diagonal(const T &rhs)
Definition: Tensor.h:205
void evaluateHessian(ParticleSet &P, HessVector &grad_grad_psi) override
void computeU3(const ParticleSet &P, int iat, const DistRow &dist, RealType *restrict u, RealType *restrict du, RealType *restrict d2u, bool triangle=false)
intenal function to compute
size_type current() const
Definition: PooledMemory.h:76
virtual void mw_accept_rejectMove(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, const std::vector< bool > &isAccepted, bool safe_to_delay=false) const
moves of the iat-th particle on some walkers in a batch is accepted.
std::vector< std::reference_wrapper< T > > RefVector
virtual void mw_evaluateLog(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, const RefVector< ParticleSet::ParticleGradient > &G_list, const RefVector< ParticleSet::ParticleLaplacian > &L_list) const
evaluate from scratch the same type WaveFunctionComponent of multiple walkers
QMCTraits::RealType RealType
Vector< int, OffloadPinnedAllocator< int > > grp_ids
the group_id of each particle
Vector< T, OffloadPinnedAllocator< T > > mw_cur_allu
memory pool for cur_u, cur_du, cur_d2u [3][Nw][N_padded]. 3 is for value, first and second derivative...
void mw_ratioGrad(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< PsiValue > &ratios, TWFGrads< CT > &grad_new) const
void acquireResource(ResourceCollection &collection, const RefVectorWithLeader< WaveFunctionComponent > &wfc_list) const override
acquire a shared resource from a collection
const size_t NumGroups
number of groups of the target particleset
LogValue evaluateGL(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L, bool fromscratch=false) override
compute G and L after the sweep
void evaluateRatiosAlltoOne(ParticleSet &P, std::vector< ValueType > &ratios) override
Precision RealType
Definition: QMCTypes.h:37
Declaraton of ParticleAttrib<T>
virtual void mw_evaluateRatios(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< const VirtualParticleSet > &vp_list, std::vector< std::vector< ValueType >> &ratios) const
evaluate ratios to evaluate the non-local PP multiple walkers
void evaluateDerivatives(ParticleSet &P, const opt_variables_type &active, Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi) override
void evaluateRatios(const VirtualParticleSet &VP, std::vector< ValueType > &ratios) override
void free()
free allocated memory and clear status variables
OrbitalSetTraits< ValueType >::HessVector HessVector
LatticeGaussianProduct::ValueType ValueType
void checkOutVariables(const opt_variables_type &active) override
check out optimizable variables
void mw_recompute(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, const std::vector< bool > &recompute) const override
ResourceHandle< RS > lendResource()
Vector< T, OffloadPinnedAllocator< T > > mw_vals
virtual void mw_calcRatio(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< PsiValue > &ratios) const
compute the ratio of the new to old WaveFunctionComponent value of multiple walkers ...
void mw_accept_rejectMove(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, const std::vector< bool > &isAccepted, bool safe_to_delay=false) const override
moves of the iat-th particle on some walkers in a batch is accepted.
RealType KEcorr
Correction.
FT FuncType
alias FuncType
SIMD version of functions in algorithm.
T1 * lendReference(size_type n)
Definition: PooledMemory.h:154
void push_back(OptimizableObject &obj)
const size_t N
number of particles
void mw_calcRatio(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< PsiValue > &ratios) const override
void copyFromBuffer(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
Vector< T, OffloadPinnedAllocator< T > > mw_allUat
memory pool for Uat, dUat, d2Uat [Nw][N_padded] + [Nw][DIM][N_padded] + [Nw][N_padded] ...
TwoBodyJastrowMultiWalkerMem(const TwoBodyJastrowMultiWalkerMem &)
void acceptMove(ParticleSet &P, int iat, bool safe_to_delay=false) override
a move for iat-th particle is accepted.
void add(std::complex< T1 > &x)
Definition: PooledMemory.h:113
LogValue evaluateLog(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) override
evaluate the value of the WaveFunctionComponent from scratch