28 template<PlatformKind PL,
typename VT,
typename FPVT>
36 std::unique_ptr<Resource>
makeClone()
const override 38 return std::make_unique<DiracDeterminantBatchedMultiWalkerResource>(*this);
61 template<PlatformKind PL,
typename VT,
typename FPVT>
68 det_engine_(NumOrbitals, ndelay),
70 matrix_inverter_kind_(matrix_inverter_kind),
74 static_assert(std::is_same<SPOSet::ValueType, typename UpdateEngine::Value>::value);
84 template<PlatformKind PL,
typename VT,
typename FPVT>
88 host_inverter_.invert_transpose(psiM, psiMinv, log_value_);
93 auto& engine_psiMinv = psiMinv_;
94 dummy_vmt.attachReference(engine_psiMinv.data(), engine_psiMinv.rows(), engine_psiMinv.cols());
98 template<PlatformKind PL,
typename VT,
typename FPVT>
105 ScopedTimer inverse_timer(wfc_leader.InverseTimer);
106 const auto nw = wfc_list.size();
111 engine_list.reserve(nw);
113 mw_res.log_values.
resize(nw);
115 for (
int iw = 0; iw < nw; iw++)
118 engine_list.push_back(
det.det_engine_);
119 mw_res.log_values[iw] = {0.0, 0.0};
125 for (
int iw = 0; iw < nw; ++iw)
128 det.log_value_ = mw_res.log_values[iw];
133 for (
int iw = 0; iw < nw; iw++)
137 det.host_inverter_.invert_transpose(logdetT_list[iw].
get(), psiMinv,
det.log_value_);
143 for (
int iw = 0; iw < nw; ++iw)
146 auto& engine_psiMinv =
det.psiMinv_;
147 det.dummy_vmt.attachReference(engine_psiMinv.data(), engine_psiMinv.rows(), engine_psiMinv.cols());
153 template<PlatformKind PL,
typename VT,
typename FPVT>
159 psiMinv_.resize(norb, getAlignedSize<Value>(norb));
160 psiM_vgl.resize(nel * norb);
162 psiM_temp.attachReference(psiM_vgl, psiM_vgl.data(0), nel, norb);
163 psiM_host.attachReference(psiM_vgl.data(0), nel, norb);
164 dpsiM.attachReference(reinterpret_cast<Grad*>(psiM_vgl.data(1)), nel, norb);
165 d2psiM.attachReference(psiM_vgl.data(4), nel, norb);
167 psiV.resize(NumOrbitals);
168 psiV_host_view.attachReference(psiV.data(), NumOrbitals);
169 dpsiV.resize(NumOrbitals);
170 dpsiV_host_view.attachReference(dpsiV.data(), NumOrbitals);
171 d2psiV.resize(NumOrbitals);
172 d2psiV_host_view.attachReference(d2psiV.data(), NumOrbitals);
173 dspin_psiV.resize(NumOrbitals);
174 dspin_psiV_host_view.attachReference(dspin_psiV.data(), NumOrbitals);
177 template<PlatformKind PL,
typename VT,
typename FPVT>
182 const int WorkingIndex = iat - FirstIndex;
183 Grad g =
simd::dot(psiMinv_[WorkingIndex], dpsiM[WorkingIndex], NumOrbitals);
188 template<PlatformKind PL,
typename VT,
typename FPVT>
192 std::vector<Grad>& grad_now)
const 199 const int nw = wfc_list.size();
200 std::vector<const Value*> dpsiM_row_list(nw,
nullptr);
202 engine_list.reserve(nw);
204 const int WorkingIndex = iat - FirstIndex;
205 for (
int iw = 0; iw < nw; iw++)
210 dpsiM_row_list[iw] =
det.psiM_vgl.device_data() + psiM_vgl.capacity() + NumOrbitals * WorkingIndex *
DIM;
211 engine_list.push_back(
det.det_engine_);
214 UpdateEngine::mw_evalGrad(engine_list, wfc_leader.mw_res_handle_.getResource().engine_rsc, mw_res.psiMinv_refs,
215 dpsiM_row_list, WorkingIndex, grad_now);
218 for (
int iw = 0; iw < nw; iw++)
219 checkG(grad_now[iw]);
223 template<PlatformKind PL,
typename VT,
typename FPVT>
229 Phi->evaluate_spin(P, iat, psiV_host_view, dspin_psiV_host_view);
231 const int WorkingIndex = iat - FirstIndex;
232 Grad g =
simd::dot(psiMinv_[WorkingIndex], dpsiM[WorkingIndex], NumOrbitals);
239 template<PlatformKind PL,
typename VT,
typename FPVT>
244 std::vector<Grad>& grad_now,
245 std::vector<ComplexType>& spingrad_now)
const 250 auto& mw_dspin = mw_res.mw_dspin;
253 const int nw = wfc_list.size();
254 const int num_orbitals = wfc_leader.Phi->size();
255 mw_dspin.resize(nw, num_orbitals);
264 for (
int iw = 0; iw < wfc_list.size(); iw++)
267 phi_list.push_back(*
det.Phi);
268 psi_v_list.push_back(
det.psiV_host_view);
269 grad_v_list.push_back(
det.dpsiV_host_view);
270 lap_v_list.push_back(
det.d2psiV_host_view);
276 std::vector<const Value*> dpsiM_row_list(nw,
nullptr);
278 engine_list.reserve(nw);
280 const int WorkingIndex = iat - FirstIndex;
281 for (
int iw = 0; iw < nw; iw++)
286 dpsiM_row_list[iw] =
det.psiM_vgl.device_data() + psiM_vgl.capacity() + NumOrbitals * WorkingIndex *
DIM;
287 engine_list.push_back(
det.det_engine_);
290 UpdateEngine::mw_evalGradWithSpin(engine_list, wfc_leader.mw_res_handle_.getResource().engine_rsc,
291 mw_res.psiMinv_refs, dpsiM_row_list, mw_dspin, WorkingIndex, grad_now,
295 for (
int iw = 0; iw < nw; iw++)
296 checkG(grad_now[iw]);
300 template<PlatformKind PL,
typename VT,
typename FPVT>
306 UpdateMode = ORB_PBYP_PARTIAL;
310 Phi->evaluateVGL(P, iat, psiV_host_view, dpsiV_host_view, d2psiV_host_view);
315 const int WorkingIndex = iat - FirstIndex;
316 curRatio =
simd::dot(psiMinv_[WorkingIndex], psiV.data(), NumOrbitals);
317 grad_iat +=
static_cast<Value>(
static_cast<PsiValue>(1.0) / curRatio) *
318 simd::dot(psiMinv_[WorkingIndex], dpsiV.data(), NumOrbitals);
323 template<PlatformKind PL,
typename VT,
typename FPVT>
327 std::vector<PsiValue>& ratios,
328 std::vector<Grad>& grad_new)
const 333 auto& phi_vgl_v = mw_res.phi_vgl_v;
334 auto& ratios_local = mw_res.ratios_local;
335 auto& grad_new_local = mw_res.grad_new_local;
339 phi_list.reserve(wfc_list.size());
341 engine_list.reserve(wfc_list.size());
342 const int WorkingIndex = iat - FirstIndex;
343 for (
int iw = 0; iw < wfc_list.size(); iw++)
346 phi_list.push_back(*
det.Phi);
347 engine_list.push_back(
det.det_engine_);
350 auto psiMinv_row_dev_ptr_list =
351 UpdateEngine::mw_getInvRow(engine_list, wfc_leader.mw_res_handle_.getResource().engine_rsc, mw_res.psiMinv_refs,
352 WorkingIndex, !Phi->isOMPoffload());
354 phi_vgl_v.resize(DIM_VGL, wfc_list.size(), NumOrbitals);
355 ratios_local.resize(wfc_list.size());
356 grad_new_local.resize(wfc_list.size());
358 wfc_leader.Phi->mw_evaluateVGLandDetRatioGrads(phi_list, p_list, iat, psiMinv_row_dev_ptr_list, phi_vgl_v,
359 ratios_local, grad_new_local);
362 wfc_leader.UpdateMode = ORB_PBYP_PARTIAL;
363 for (
int iw = 0; iw < wfc_list.size(); iw++)
366 det.UpdateMode = ORB_PBYP_PARTIAL;
367 ratios[iw] =
det.curRatio = ratios_local[iw];
368 grad_new[iw] += grad_new_local[iw];
372 template<PlatformKind PL,
typename VT,
typename FPVT>
377 std::vector<PsiValue>& ratios,
378 std::vector<Grad>& grad_new,
379 std::vector<ComplexType>& spingrad_new)
const 384 auto& phi_vgl_v = mw_res.phi_vgl_v;
385 auto& ratios_local = mw_res.ratios_local;
386 auto& grad_new_local = mw_res.grad_new_local;
387 auto& spingrad_new_local = mw_res.spingrad_new_local;
391 phi_list.reserve(wfc_list.size());
393 engine_list.reserve(wfc_list.size());
394 const int WorkingIndex = iat - FirstIndex;
395 for (
int iw = 0; iw < wfc_list.size(); iw++)
398 phi_list.push_back(*
det.Phi);
399 engine_list.push_back(
det.det_engine_);
402 auto psiMinv_row_dev_ptr_list =
403 UpdateEngine::mw_getInvRow(engine_list, wfc_leader.mw_res_handle_.getResource().engine_rsc, mw_res.psiMinv_refs,
404 WorkingIndex, !Phi->isOMPoffload());
406 phi_vgl_v.resize(DIM_VGL, wfc_list.size(), NumOrbitals);
407 ratios_local.resize(wfc_list.size());
408 grad_new_local.resize(wfc_list.size());
409 spingrad_new_local.resize(wfc_list.size());
411 wfc_leader.Phi->mw_evaluateVGLandDetRatioGradsWithSpin(phi_list, p_list, iat, psiMinv_row_dev_ptr_list, phi_vgl_v,
412 ratios_local, grad_new_local, spingrad_new_local);
415 wfc_leader.UpdateMode = ORB_PBYP_PARTIAL;
416 for (
int iw = 0; iw < wfc_list.size(); iw++)
419 det.UpdateMode = ORB_PBYP_PARTIAL;
420 ratios[iw] =
det.curRatio = ratios_local[iw];
421 grad_new[iw] += grad_new_local[iw];
422 spingrad_new[iw] += spingrad_new_local[iw];
426 template<PlatformKind PL,
typename VT,
typename FPVT>
433 UpdateMode = ORB_PBYP_PARTIAL;
437 Phi->evaluateVGL_spin(P, iat, psiV_host_view, dpsiV_host_view, d2psiV_host_view, dspin_psiV_host_view);
442 const int WorkingIndex = iat - FirstIndex;
443 curRatio =
simd::dot(psiMinv_[WorkingIndex], psiV.data(), NumOrbitals);
444 grad_iat +=
static_cast<Value>(
static_cast<PsiValue>(1.0) / curRatio) *
445 simd::dot(psiMinv_[WorkingIndex], dpsiV.data(), NumOrbitals);
446 spingrad_iat +=
static_cast<Value>(
static_cast<PsiValue>(1.0) / curRatio) *
447 simd::dot(psiMinv_[WorkingIndex], dspin_psiV.data(), NumOrbitals);
455 template<PlatformKind PL,
typename VT,
typename FPVT>
460 std::ostringstream msg;
461 msg <<
"DiracDeterminantBatched::acceptMove curRatio is " << curRatio <<
"! Report a bug." << std::endl;
462 throw std::runtime_error(msg.str());
464 const int WorkingIndex = iat - FirstIndex;
469 det_engine_.updateRow(psiMinv_, WorkingIndex, psiV, curRatio);
470 if (UpdateMode == ORB_PBYP_PARTIAL)
472 simd::copy(dpsiM[WorkingIndex], dpsiV.data(), NumOrbitals);
473 simd::copy(d2psiM[WorkingIndex], d2psiV.data(), NumOrbitals);
479 template<PlatformKind PL,
typename VT,
typename FPVT>
484 const std::vector<bool>& isAccepted,
485 bool safe_to_delay)
const 490 auto& phi_vgl_v = mw_res.phi_vgl_v;
491 auto& ratios_local = mw_res.ratios_local;
495 const int nw = wfc_list.size();
497 for (
int iw = 0; iw < nw; iw++)
500 const int n_accepted = count;
503 engine_list.reserve(nw);
504 std::vector<Value*> psiM_g_dev_ptr_list(n_accepted,
nullptr);
505 std::vector<Value*> psiM_l_dev_ptr_list(n_accepted,
nullptr);
507 const int WorkingIndex = iat - FirstIndex;
508 for (
int iw = 0, count = 0; iw < nw; iw++)
512 engine_list.push_back(
det.det_engine_);
515 psiM_g_dev_ptr_list[count] =
det.psiM_vgl.device_data() + psiM_vgl.capacity() + NumOrbitals * WorkingIndex *
DIM;
516 psiM_l_dev_ptr_list[count] =
det.psiM_vgl.device_data() + psiM_vgl.capacity() * 4 + NumOrbitals * WorkingIndex;
520 std::ostringstream msg;
521 msg <<
"DiracDeterminantBatched::mw_accept_rejectMove det.curRatio is " <<
det.curRatio <<
"! Report a bug." 523 throw std::runtime_error(msg.str());
531 UpdateEngine::mw_accept_rejectRow(engine_list, wfc_leader.mw_res_handle_.getResource().engine_rsc,
532 mw_res.psiMinv_refs, WorkingIndex, psiM_g_dev_ptr_list, psiM_l_dev_ptr_list,
533 isAccepted, phi_vgl_v, ratios_local);
536 UpdateEngine::mw_updateInvMat(engine_list, wfc_leader.mw_res_handle_.getResource().engine_rsc, mw_res.psiMinv_refs);
541 template<PlatformKind PL,
typename VT,
typename FPVT>
547 template<PlatformKind PL,
typename VT,
typename FPVT>
551 if (UpdateMode == ORB_PBYP_PARTIAL)
554 auto* psiM_vgl_ptr = psiM_vgl.data();
556 PRAGMA_OFFLOAD(
"omp target update to(psiM_vgl_ptr[psiM_vgl.capacity():psiM_vgl.capacity()*4])")
560 template<PlatformKind PL,
typename VT,
typename FPVT>
567 const auto nw = wfc_list.size();
569 engine_list.reserve(nw);
570 for (
int iw = 0; iw < nw; iw++)
573 engine_list.push_back(
det.det_engine_);
578 UpdateEngine::mw_updateInvMat(engine_list, mw_res.engine_rsc, mw_res.psiMinv_refs);
585 UpdateEngine::mw_transferAinv_D2H(engine_list, mw_res.engine_rsc, mw_res.psiMinv_refs);
587 if (UpdateMode == ORB_PBYP_PARTIAL)
590 psiM_vgl_list.reserve(nw);
591 for (
int iw = 0; iw < nw; iw++)
594 psiM_vgl_list.push_back(
det.psiM_vgl);
597 auto&
queue = mw_res.engine_rsc.queue;
600 const size_t stride = psiM_vgl.capacity();
602 queue.enqueueD2H(psiM_vgl, stride * 4, stride);
609 template<PlatformKind PL,
typename VT,
typename FPVT>
613 for (
size_t i = 0, iat = FirstIndex; i < NumPtcls; ++i, ++iat)
618 L[iat] += lap -
dot(rv, rv);
622 template<PlatformKind PL,
typename VT,
typename FPVT>
631 evaluateLog(P, G, L);
634 if (UpdateMode == ORB_PBYP_RATIO)
637 Phi->evaluate_notranspose(P, FirstIndex, LastIndex, psiM_host, dpsiM, d2psiM);
639 UpdateMode = ORB_WALKER;
645 template<PlatformKind PL,
typename VT,
typename FPVT>
650 bool fromscratch)
const 655 mw_evaluateLog(wfc_list, p_list, G_list, L_list);
658 const auto nw = wfc_list.size();
660 engine_list.reserve(nw);
662 if (UpdateMode == ORB_PBYP_RATIO)
670 phi_list.reserve(wfc_list.size());
671 psiM_temp_list.reserve(nw);
672 dpsiM_list.reserve(nw);
673 d2psiM_list.reserve(nw);
675 for (
int iw = 0; iw < nw; iw++)
678 engine_list.push_back(
det.det_engine_);
679 phi_list.push_back(*
det.Phi);
680 psiM_temp_list.push_back(
det.psiM_host);
681 dpsiM_list.push_back(
det.dpsiM);
682 d2psiM_list.push_back(
det.d2psiM);
685 Phi->mw_evaluate_notranspose(phi_list, p_list, FirstIndex, LastIndex, psiM_temp_list, dpsiM_list, d2psiM_list);
688 for (
int iw = 0; iw < nw; iw++)
697 auto& my_psiM_vgl =
det.psiM_vgl;
698 auto* psiM_vgl_ptr = my_psiM_vgl.data();
700 PRAGMA_OFFLOAD(
"omp target update from(psiM_vgl_ptr[my_psiM_vgl.capacity():my_psiM_vgl.capacity()*4])")
701 assert(dpsiM_from_device ==
det.dpsiM);
702 assert(d2psiM_from_device ==
det.d2psiM);
705 det.UpdateMode = ORB_WALKER;
706 det.computeGL(G_list[iw], L_list[iw]);
711 template<PlatformKind PL,
typename VT,
typename FPVT>
714 buf.
add(psiMinv_.first_address(), psiMinv_.last_address());
715 buf.
add(dpsiM.first_address(), dpsiM.last_address());
716 buf.
add(d2psiM.first_address(), d2psiM.last_address());
720 template<PlatformKind PL,
typename VT,
typename FPVT>
726 evaluateGL(P, P.
G, P.
L, fromscratch);
728 buf.
put(psiMinv_.first_address(), psiMinv_.last_address());
729 buf.
put(dpsiM.first_address(), dpsiM.last_address());
730 buf.
put(d2psiM.first_address(), d2psiM.last_address());
735 template<PlatformKind PL,
typename VT,
typename FPVT>
739 buf.
get(psiMinv_.first_address(), psiMinv_.last_address());
740 buf.
get(dpsiM.first_address(), dpsiM.last_address());
741 buf.
get(d2psiM.first_address(), d2psiM.last_address());
743 auto* psiM_vgl_ptr = psiM_vgl.data();
744 const size_t psiM_vgl_stride = psiM_vgl.capacity();
746 PRAGMA_OFFLOAD(
"omp target update to(psiM_vgl_ptr[psiM_vgl_stride:psiM_vgl_stride*4])")
754 template<PlatformKind PL,
typename VT,
typename FPVT>
758 UpdateMode = ORB_PBYP_RATIO;
759 const int WorkingIndex = iat - FirstIndex;
762 Phi->evaluateValue(P, iat, psiV_host_view);
766 curRatio =
simd::dot(psiMinv_[WorkingIndex], psiV.data(), NumOrbitals);
771 template<PlatformKind PL,
typename VT,
typename FPVT>
775 std::vector<PsiValue>& ratios)
const 780 auto& phi_vgl_v = mw_res.phi_vgl_v;
781 auto& ratios_local = mw_res.ratios_local;
782 auto& grad_new_local = mw_res.grad_new_local;
787 phi_list.reserve(wfc_list.size());
789 engine_list.reserve(wfc_list.size());
791 const int WorkingIndex = iat - FirstIndex;
792 for (
int iw = 0; iw < wfc_list.size(); iw++)
795 phi_list.push_back(*
det.Phi);
796 engine_list.push_back(
det.det_engine_);
799 auto psiMinv_row_dev_ptr_list =
800 UpdateEngine::mw_getInvRow(engine_list, wfc_leader.mw_res_handle_.getResource().engine_rsc, mw_res.psiMinv_refs,
801 WorkingIndex, !Phi->isOMPoffload());
803 phi_vgl_v.resize(DIM_VGL, wfc_list.size(), NumOrbitals);
804 ratios_local.resize(wfc_list.size());
805 grad_new_local.resize(wfc_list.size());
809 wfc_leader.Phi->mw_evaluateVGLandDetRatioGrads(phi_list, p_list, iat, psiMinv_row_dev_ptr_list, phi_vgl_v,
810 ratios_local, grad_new_local);
813 wfc_leader.UpdateMode = ORB_PBYP_RATIO;
814 for (
int iw = 0; iw < wfc_list.size(); iw++)
817 det.UpdateMode = ORB_PBYP_RATIO;
818 ratios[iw] =
det.curRatio = ratios_local[iw];
822 template<PlatformKind PL,
typename VT,
typename FPVT>
827 const int WorkingIndex = VP.
refPtcl - FirstIndex;
828 std::copy_n(psiMinv_[WorkingIndex], d2psiV.size(), d2psiV.data());
832 Phi->evaluateDetRatios(VP, psiV_host_view, d2psiV_host_view, ratios);
836 template<PlatformKind PL,
typename VT,
typename FPVT>
839 const std::pair<ValueVector, ValueVector>& spinor_multipler,
840 std::vector<Value>& ratios)
844 const int WorkingIndex = VP.
refPtcl - FirstIndex;
845 std::copy_n(psiMinv_[WorkingIndex], d2psiV.size(), d2psiV.data());
849 Phi->evaluateDetSpinorRatios(VP, psiV_host_view, spinor_multipler, d2psiV_host_view, ratios);
853 template<PlatformKind PL,
typename VT,
typename FPVT>
857 std::vector<std::vector<Value>>& ratios)
const 860 const size_t nw = wfc_list.size();
864 std::vector<const Value*> invRow_ptr_list;
865 phi_list.reserve(nw);
866 psiV_list.reserve(nw);
867 invRow_ptr_list.reserve(nw);
871 for (
size_t iw = 0; iw < nw; iw++)
875 const int WorkingIndex = vp.refPtcl - FirstIndex;
877 phi_list.push_back(*
det.Phi);
878 psiV_list.push_back(
det.psiV_host_view);
879 if (Phi->isOMPoffload())
880 invRow_ptr_list.push_back(
det.psiMinv_.device_data() + WorkingIndex * psiMinv_.cols());
882 invRow_ptr_list.push_back(
det.psiMinv_[WorkingIndex]);
888 Phi->mw_evaluateDetRatios(phi_list, vp_list, psiV_list, invRow_ptr_list, ratios);
892 template<PlatformKind PL,
typename VT,
typename FPVT>
895 std::vector<ValueType>& ratios,
898 const int WorkingIndex = VP.
refPtcl - FirstIndex;
899 assert(WorkingIndex >= 0);
900 std::copy_n(psiMinv_[WorkingIndex], d2psiV.size(), d2psiV.data());
901 Phi->evaluateDerivRatios(VP, optvars, psiV_host_view, d2psiV_host_view, ratios, dratios, FirstIndex, LastIndex);
904 template<PlatformKind PL,
typename VT,
typename FPVT>
909 Phi->evaluateValue(P, -1, psiV_host_view);
911 for (
int i = 0; i < psiMinv_.rows(); i++)
912 ratios[FirstIndex + i] =
simd::dot(psiMinv_[i], psiV.data(), NumOrbitals);
915 template<PlatformKind PL,
typename VT,
typename FPVT>
918 grad_source_psiM.resize(NumPtcls, NumOrbitals);
919 grad_lapl_source_psiM.resize(NumPtcls, NumOrbitals);
920 grad_grad_source_psiM.resize(NumPtcls, NumOrbitals);
921 phi_alpha_Minv.resize(NumPtcls, NumOrbitals);
922 grad_phi_Minv.resize(NumPtcls, NumOrbitals);
923 lapl_phi_Minv.resize(NumPtcls, NumOrbitals);
924 grad_phi_alpha_Minv.resize(NumPtcls, NumOrbitals);
927 template<PlatformKind PL,
typename VT,
typename FPVT>
934 if (Phi->hasIonDerivs())
936 resizeScratchObjectsForIonDerivs();
937 Phi->evaluateGradSource(P, FirstIndex, LastIndex, source, iat, grad_source_psiM);
939 for (
int i = 0; i < psiMinv_.rows(); i++)
940 g +=
simd::dot(psiMinv_[i], grad_source_psiM[i], NumOrbitals);
946 template<PlatformKind PL,
typename VT,
typename FPVT>
950 grad_grad_source_psiM.resize(psiMinv_.rows(), NumOrbitals);
952 Matrix<Value> psiM_temp_host(psiM_temp.data(), psiM_temp.rows(), psiM_temp.cols());
953 Phi->evaluate_notranspose(P, FirstIndex, LastIndex, psiM_temp_host, dpsiM, grad_grad_source_psiM);
954 invertPsiM(psiM_temp, psiMinv_);
956 phi_alpha_Minv = 0.0;
959 grad_phi_alpha_Minv = 0.0;
962 for (
int i = 0, iat = FirstIndex; i < NumPtcls; i++, iat++)
968 hess_tmp =
simd::dot(psiMinv_[i], grad_grad_source_psiM[i], NumOrbitals);
973 template<PlatformKind PL,
typename VT,
typename FPVT>
982 if (Phi->hasIonDerivs())
984 resizeScratchObjectsForIonDerivs();
985 Phi->evaluateGradSource(P, FirstIndex, LastIndex, source, iat, grad_source_psiM, grad_grad_source_psiM,
986 grad_lapl_source_psiM);
989 phi_alpha_Minv = 0.0;
992 grad_phi_alpha_Minv = 0.0;
993 for (
int i = 0; i < NumPtcls; i++)
994 for (
int j = 0; j < NumOrbitals; j++)
996 lapl_phi_Minv(i, j) = 0.0;
997 for (
int k = 0; k < NumOrbitals; k++)
998 lapl_phi_Minv(i, j) += d2psiM(i, k) * psiMinv_(j, k);
1000 for (
int dim = 0; dim <
OHMMS_DIM; dim++)
1002 for (
int i = 0; i < NumPtcls; i++)
1003 for (
int j = 0; j < NumOrbitals; j++)
1005 for (
int k = 0; k < NumOrbitals; k++)
1007 phi_alpha_Minv(i, j)[dim] += grad_source_psiM(i, k)[dim] * psiMinv_(j, k);
1008 grad_phi_Minv(i, j)[dim] += dpsiM(i, k)[dim] * psiMinv_(j, k);
1009 for (
int dim_el = 0; dim_el <
OHMMS_DIM; dim_el++)
1010 grad_phi_alpha_Minv(i, j)(dim, dim_el) += grad_grad_source_psiM(i, k)(dim, dim_el) * psiMinv_(j, k);
1014 for (
int i = 0, iel = FirstIndex; i < NumPtcls; i++, iel++)
1018 for (
int dim = 0; dim <
OHMMS_DIM; dim++)
1019 for (
int dim_el = 0; dim_el <
OHMMS_DIM; dim_el++)
1020 dval(dim, dim_el) = grad_phi_alpha_Minv(i, i)(dim, dim_el);
1021 for (
int j = 0; j < NumOrbitals; j++)
1023 gradPsi += grad_source_psiM(i, j) * psiMinv_(i, j);
1024 for (
int dim = 0; dim <
OHMMS_DIM; dim++)
1026 dval(dim, k) -= phi_alpha_Minv(j, i)[dim] * grad_phi_Minv(i, j)[k];
1028 for (
int dim = 0; dim <
OHMMS_DIM; dim++)
1031 grad_grad[dim][iel][k] += dval(dim, k);
1032 for (
int j = 0; j < NumOrbitals; j++)
1035 lapl_grad[dim][iel] += grad_lapl_source_psiM(i, j)[dim] * psiMinv_(i, j);
1038 for (
int dim_el = 0; dim_el <
OHMMS_DIM; dim_el++)
1039 lapl_grad[dim][iel] -= (
Real)2.0 * grad_phi_alpha_Minv(j, i)(dim, dim_el) * grad_phi_Minv(i, j)[dim_el];
1042 lapl_grad[dim][iel] -= phi_alpha_Minv(j, i)[dim] * lapl_phi_Minv(i, j);
1044 for (
int dim_el = 0; dim_el <
OHMMS_DIM; dim_el++)
1045 lapl_grad[dim][iel] +=
1046 (
Real)2.0 * phi_alpha_Minv(j, i)[dim] * grad_phi_Minv(i, i)[dim_el] * grad_phi_Minv(i, j)[dim_el];
1064 template<PlatformKind PL,
typename VT,
typename FPVT>
1075 template<PlatformKind PL,
typename VT,
typename FPVT>
1083 const std::vector<bool> recompute_all(wfc_list.size(),
true);
1084 mw_recompute(wfc_list, p_list, recompute_all);
1086 for (
int iw = 0; iw < wfc_list.size(); iw++)
1089 det.computeGL(G_list[iw], L_list[iw]);
1093 template<PlatformKind PL,
typename VT,
typename FPVT>
1099 UpdateMode = ORB_WALKER;
1100 Phi->evaluate_notranspose(P, FirstIndex, LastIndex, psiM_host, dpsiM, d2psiM);
1101 auto* psiM_vgl_ptr = psiM_vgl.data();
1103 PRAGMA_OFFLOAD(
"omp target update to(psiM_vgl_ptr[psiM_vgl.capacity():psiM_vgl.capacity()*4])")
1105 invertPsiM(psiM_temp, psiMinv_);
1108 template<PlatformKind PL,
typename VT,
typename FPVT>
1111 const std::vector<bool>& recompute)
const 1114 const auto nw = wfc_list.size();
1119 std::vector<Matrix<Value>> psiM_host_views;
1126 wfc_filtered_list.reserve(nw);
1127 p_filtered_list.reserve(nw);
1128 phi_list.reserve(nw);
1129 psiM_host_views.reserve(nw);
1130 psiM_temp_list.reserve(nw);
1131 dpsiM_list.reserve(nw);
1132 d2psiM_list.reserve(nw);
1133 psiMinv_list.reserve(nw);
1135 for (
int iw = 0; iw < nw; iw++)
1138 wfc_filtered_list.push_back(wfc_list[iw]);
1139 p_filtered_list.push_back(p_list[iw]);
1142 phi_list.push_back(*
det.Phi);
1143 psiM_temp_list.push_back(
det.psiM_temp);
1144 psiM_host_list.push_back(
det.psiM_host);
1145 dpsiM_list.push_back(
det.dpsiM);
1146 d2psiM_list.push_back(
det.d2psiM);
1147 psiMinv_list.push_back(
det.psiMinv_);
1150 if (!wfc_filtered_list.size())
1158 wfc_leader.Phi->mw_evaluate_notranspose(phi_list, p_filtered_list, wfc_leader.FirstIndex, wfc_leader.LastIndex,
1159 psiM_host_list, dpsiM_list, d2psiM_list);
1162 mw_invertPsiM(wfc_filtered_list, psiM_temp_list, psiMinv_list);
1168 psiM_vgl_list.reserve(nw);
1169 for (
int iw = 0; iw < wfc_filtered_list.size(); iw++)
1172 psiM_vgl_list.push_back(
det.psiM_vgl);
1173 det.UpdateMode = ORB_WALKER;
1176 auto&
queue = wfc_leader.mw_res_handle_.getResource().engine_rsc.queue;
1179 const size_t stride = psiM_vgl.capacity();
1181 queue.enqueueH2D(psiM_vgl, stride * 4, stride);
1187 template<PlatformKind PL,
typename VT,
typename FPVT>
1193 Phi->evaluateDerivatives(P, active, dlogpsi, dhpsioverpsi, FirstIndex, LastIndex);
1196 template<PlatformKind PL,
typename VT,
typename FPVT>
1201 Phi->evaluateDerivativesWF(P, active, dlogpsi, FirstIndex, LastIndex);
1204 template<PlatformKind PL,
typename VT,
typename FPVT>
1211 template<PlatformKind PL,
typename VT,
typename FPVT>
1213 std::unique_ptr<SPOSet>&& spo)
const 1215 return std::make_unique<DiracDeterminantBatched<PL, VT, FPVT>>(std::move(spo), FirstIndex, LastIndex, ndelay_,
1216 matrix_inverter_kind_);
1219 template<PlatformKind PL,
typename VT,
typename FPVT>
1222 collection.
addResource(std::make_unique<DiracDeterminantBatchedMultiWalkerResource>());
1223 Phi->createResource(collection);
1224 collection.
addResource(std::make_unique<DetInverter>());
1227 template<PlatformKind PL,
typename VT,
typename FPVT>
1234 auto& mw_res = wfc_leader.mw_res_handle_.getResource();
1241 phi_list.push_back(*
det.Phi);
1244 wfc_leader.Phi->acquireResource(collection, phi_list);
1248 template<PlatformKind PL,
typename VT,
typename FPVT>
1260 phi_list.push_back(*
det.Phi);
1262 wfc_leader.Phi->releaseResource(collection, phi_list);
1267 #if defined(ENABLE_CUDA) && defined(ENABLE_OFFLOAD) 1270 #if defined(ENABLE_SYCL) && defined(ENABLE_OFFLOAD) void copyFromBuffer(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
typename WFT::Value Value
void resizeScratchObjectsForIonDerivs()
Resize all temporary arrays required for force computation.
size_t addResource(std::unique_ptr< Resource > &&res, bool noprint=false)
WaveFunctionComponent::PsiValue PsiValue
void takebackResource(ResourceHandle< RS > &res_handle)
LogValue evaluateGL(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L, bool fromscratch) override
compute gradients and laplacian of the TWF with respect to each particle.
helper functions for EinsplineSetBuilder
Tensor< T, D >::Type_t det(const Tensor< T, D > &a)
T dot(const T *restrict a, const T *restrict b, int n, TRES res=TRES())
dot product
void mw_ratioGrad(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< PsiValue > &ratios, std::vector< Grad > &grad_new) const override
void restore(int iat) override
move was rejected.
std::vector< Value > spingrad_new_local
multi walker of spingrads
void computeGL(ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) const
compute G and L assuming psiMinv, dpsiM, d2psiM are ready for use
typename WFT::LogValue LogValue
void acquireResource(ResourceCollection &collection, const RefVectorWithLeader< WaveFunctionComponent > &wfc_list) const override
acquire a shared resource from a collection
void mw_completeUpdates(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list) const override
complete all the delayed or asynchronous operations for all the walkers in a batch before leaving the...
DetMatInvertor
determinant matrix inverter select
A ParticleSet that handles virtual moves of a selected particle of a given physical ParticleSet Virtu...
typename DetInverterSelector< PL, FPVT >::Inverter DetInverter
Grad evalGradWithSpin(ParticleSet &P, int iat, ComplexType &spingrad) override
return the current spin gradient for the iat-th particle Default implementation assumes that WaveFunc...
void mw_evalGrad(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< Grad > &grad_now) const override
int refPtcl
Reference particle.
QTBase::ComplexType ComplexType
void evaluateHessian(ParticleSet &P, HessVector &grad_grad_psi) override
static void mw_invertPsiM(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVector< const DualMatrix< Value >> &logdetT_list, const RefVector< DualMatrix< Value >> &a_inv_lis)
Inverts and finds log det for a batch of matrices.
void copy(T1 *restrict target, const T2 *restrict source, size_t n)
copy function using memcpy
Attaches a unit to a Vector for IO.
std::complex< T > convertValueToLog(const std::complex< T > &logpsi)
evaluate log(psi) as log(|psi|) and phase
ParticleLaplacian L
laplacians of the particles
TWFFastDerivWrapper is a wrapper class for TrialWavefunction that provides separate and low level acc...
Grad evalGrad(ParticleSet &P, int iat) override
return the current gradient for the iat-th particle
void recompute(const ParticleSet &P) override
recompute the value of the WaveFunctionComponents which require critical accuracy.
std::vector< Value > ratios_local
multi walker of ratio
UpdateEngine::MultiWalkerResource engine_rsc
PsiValue ratioGradWithSpin(ParticleSet &P, int iat, Grad &grad_iat, ComplexType &spingrad) override
void evaluateRatios(const VirtualParticleSet &VP, std::vector< Value > &ratios) override
compute multiple ratios for a particle move
void mw_calcRatio(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< PsiValue > &ratios) const override
void evaluateDerivativesWF(ParticleSet &P, const opt_variables_type &optvars, Vector< ValueType > &dlogpsi) override
Compute the derivatives of the log of the wavefunction with respect to optimizable parameters...
void buildOptVariables(size_t nel)
An abstract class for a component of a many-body trial wave function.
std::unique_ptr< Resource > makeClone() const override
RefVector< DualMatrix< Value > > psiMinv_refs
reference to per DDB psiMinvs in a crowd
Specialized paritlce class for atomistic simulations.
void updateTo(size_type size=0, std::ptrdiff_t offset=0)
const std::unique_ptr< SPOSet > Phi
a set of single-particle orbitals used to fill in the values of the matrix
void mw_evaluateRatios(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< const VirtualParticleSet > &vp_list, std::vector< std::vector< Value >> &ratios) const override
DiracDeterminantBatchedMultiWalkerResource()
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 ...
typename WFT::PsiValue PsiValue
std::vector< Grad > grad_new_local
multi walker of grads
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > outerProduct(const TinyVector< T1, D > &lhs, const TinyVector< T2, D > &rhs)
void createResource(ResourceCollection &collection) const override
initialize a shared resource and hand it to a collection
ParticleGradient G
gradients of the particles
Grad evalGradSource(ParticleSet &P, ParticleSet &source, int iat) override
CASTTYPE & getCastedElement(size_t i) const
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
LogValue evaluateLog(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) override
evaluate from scratch pretty much everything for this single walker determinant
class to handle a set of variables that can be modified during optimizations
void evaluateSpinorRatios(const VirtualParticleSet &VP, const std::pair< ValueVector, ValueVector > &spinor_multiplier, std::vector< Value > &ratios) override
PsiValue ratioGrad(ParticleSet &P, int iat, Grad &grad_iat) override
DiracDeterminantBatchedMultiWalkerResource(const DiracDeterminantBatchedMultiWalkerResource &)
void evaluateDerivRatios(const VirtualParticleSet &VP, const opt_variables_type &optvars, std::vector< ValueType > &ratios, Matrix< ValueType > &dratios) override
evaluate ratios to evaluate the non-local PP
typename SPOSet::OffloadMWVGLArray OffloadMWVGLArray
Define determinant operators.
std::vector< std::reference_wrapper< T > > RefVector
void registerTWFFastDerivWrapper(const ParticleSet &P, TWFFastDerivWrapper &twf) const override
Register the component with the TWFFastDerivWrapper wrapper.
CASTTYPE & getCastedLeader() const
OrbitalSetTraits< ValueType >::GradMatrix GradMatrix
Declaration of DiracDeterminantBatched with a S(ingle)P(article)O(rbital)Set.
sycl::event copy_n(sycl::queue &aq, const T1 *restrict VA, size_t array_size, T2 *restrict VC, const std::vector< sycl::event > &events)
OffloadMWVGLArray phi_vgl_v
value, grads, laplacian of single-particle orbital for particle-by-particle update and multi walker [...
virtual void mw_evaluateVGLWithSpin(const RefVectorWithLeader< SPOSet > &spo_list, const RefVectorWithLeader< ParticleSet > &P_list, int iat, const RefVector< ValueVector > &psi_v_list, const RefVector< GradVector > &dpsi_v_list, const RefVector< ValueVector > &d2psi_v_list, OffloadMatrix< ComplexType > &mw_dspin) const
evaluate the values, gradients and laplacians and spin gradient of this single-particle orbital sets ...
void invertPsiM(const DualMatrix< Value > &psiM, DualMatrix< Value > &psiMinv)
single invert logdetT(psiM) as a side effect this->log_value_ gets the log determinant of logdetT ...
void mw_recompute(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, const std::vector< bool > &recompute) const override
Does a Phi->mw_evaluate_notranspose then mw_invertPsiM over a set of elements filtered based on the r...
void acceptMove(ParticleSet &P, int iat, bool safe_to_delay=false) override
move was accepted, update the real container
OrbitalSetTraits< ValueType >::HessVector HessVector
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
ResourceHandle< RS > lendResource()
void completeUpdates() override
complete any left over determinant matrix updates.
void releaseResource(ResourceCollection &collection, const RefVectorWithLeader< WaveFunctionComponent > &wfc_list) const override
return a shared resource to a collection
const int NumPtcls
number of particles which belong to this Dirac determinant
void mw_ratioGradWithSpin(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< PsiValue > &ratios, std::vector< Grad > &grad_new, std::vector< ComplexType > &spingrad_new) const override
LogValue updateBuffer(ParticleSet &P, WFBufferType &buf, bool fromscratch=false) override
For particle-by-particle move.
void evaluateDerivatives(ParticleSet &P, const opt_variables_type &active, Vector< Value > &dlogpsi, Vector< Value > &dhpsioverpsi) override
ResourceHandle< DiracDeterminantBatchedMultiWalkerResource > mw_res_handle_
void resize(int nel, int morb)
reset the size: with the number of particles and number of orbtials
DiracDeterminantBatched(std::unique_ptr< SPOSet > &&spos, int first, int last, int ndelay=1, DetMatInvertor matrix_inverter_kind=DetMatInvertor::ACCEL)
constructor
void put(std::complex< T1 > &x)
std::unique_ptr< DiracDeterminantBase > makeCopy(std::unique_ptr< SPOSet > &&spo) const override
cloning function
void evaluateRatiosAlltoOne(ParticleSet &P, std::vector< Value > &ratios) override
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.
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
void registerData(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
int getGroupID(int iat) const
return the group id of a given particle in the particle set.
OffloadMatrix< ComplexType > mw_dspin
mw spin gradients of orbitals, matrix is [nw][norb]
void mw_evalGradWithSpin(const RefVectorWithLeader< WaveFunctionComponent > &wfc_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< Grad > &grad_now, std::vector< ComplexType > &spingrad_now) const override
void add(std::complex< T1 > &x)
ResourceHandle< DetInverter > accel_inverter_
matrix inversion engine this a crowd scope resource and only the leader engine gets it ...
PsiValue ratio(ParticleSet &P, int iat) override
return the ratio only for the iat-th partcle move
void get(std::complex< T1 > &x)
DualVector< LogValue > log_values