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) 2016 Jeongnim Kim and QMCPACK developers. 6 // 7 // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign 8 // Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory 9 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory 10 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign 11 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory 12 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign 13 // Ying Wai Li, yingwaili@ornl.gov, Oak Ridge National Laboratory 14 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory 15 // 16 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign 17 ////////////////////////////////////////////////////////////////////////////////////// 18 19 20 #ifndef QMCPLUSPLUS_SINGLEPARTICLEORBITALSETBASE_H 21 #define QMCPLUSPLUS_SINGLEPARTICLEORBITALSETBASE_H 22 23 #include "OhmmsPETE/OhmmsArray.h" 24 #include "Particle/ParticleSet.h" 25 #include "Particle/VirtualParticleSet.h" 26 #include "QMCWaveFunctions/OrbitalSetTraits.h" 27 #ifdef QMC_CUDA 28 #include "type_traits/CUDATypes.h" 29 #endif 30 31 namespace qmcplusplus 32 { 33 34 class ResourceCollection; 35 36 /** base class for Single-particle orbital sets 37 * 38 * SPOSet stands for S(ingle)P(article)O(rbital)Set which contains 39 * a number of single-particle orbitals with capabilities of evaluating \f$ \psi_j({\bf r}_i)\f$ 40 */ 41 class SPOSet : public QMCTraits 42 { 43 public: 44 typedef OrbitalSetTraits<ValueType>::IndexVector_t IndexVector_t; 45 typedef OrbitalSetTraits<ValueType>::ValueVector_t ValueVector_t; 46 typedef OrbitalSetTraits<ValueType>::ValueMatrix_t ValueMatrix_t; 47 typedef OrbitalSetTraits<ValueType>::GradVector_t GradVector_t; 48 typedef OrbitalSetTraits<ValueType>::GradMatrix_t GradMatrix_t; 49 typedef OrbitalSetTraits<ValueType>::HessVector_t HessVector_t; 50 typedef OrbitalSetTraits<ValueType>::HessMatrix_t HessMatrix_t; 51 typedef OrbitalSetTraits<ValueType>::HessType HessType; 52 typedef Array<HessType, OHMMS_DIM> HessArray_t; 53 typedef OrbitalSetTraits<ValueType>::GradHessType GGGType; 54 typedef OrbitalSetTraits<ValueType>::GradHessVector_t GGGVector_t; 55 typedef OrbitalSetTraits<ValueType>::GradHessMatrix_t GGGMatrix_t; 56 typedef OrbitalSetTraits<ValueType>::VGLVector_t VGLVector_t; 57 typedef ParticleSet::Walker_t Walker_t; 58 typedef std::map<std::string, SPOSet*> SPOPool_t; 59 60 /** constructor */ 61 SPOSet(bool use_OMP_offload = false, bool ion_deriv = false, bool optimizable = false); 62 63 /** destructor 64 * 65 * Derived class destructor needs to pay extra attention to freeing memory shared among clones of SPOSet. 66 */ ~SPOSet()67 virtual ~SPOSet() {} 68 69 // accessor function to Optimizable isOptimizable()70 inline bool isOptimizable() const { return Optimizable; } 71 72 /** return the size of the orbital set 73 * Ye: this needs to be replaced by getOrbitalSetSize(); 74 */ size()75 inline int size() const { return OrbitalSetSize; } 76 getClassName()77 inline const std::string& getClassName() const { return className; } 78 79 /** print basic SPOSet information 80 */ 81 void basic_report(const std::string& pad = "") const; 82 83 /** print SPOSet information 84 */ 85 virtual void report(const std::string& pad = "") const { basic_report(pad); } 86 87 88 /** return the size of the orbitals 89 */ getOrbitalSetSize()90 inline int getOrbitalSetSize() const { return OrbitalSetSize; } 91 92 /** Query if this SPOSet uses OpenMP offload 93 */ isOMPoffload()94 inline bool isOMPoffload() const { return useOMPoffload; } 95 96 /** Query if this SPOSet has an explicit ion dependence. returns true if it does. 97 */ hasIonDerivs()98 inline bool hasIonDerivs() const { return ionDerivs; } 99 100 /// return the size of the basis set if there is any getBasisSetSize()101 virtual int getBasisSetSize() const { return 0; } 102 103 /// check a few key parameters before putting the SPO into a determinant checkObject()104 virtual void checkObject() const {} 105 106 /// create optimizable orbital rotation parameters 107 // Single Slater creation buildOptVariables(const size_t nel)108 virtual void buildOptVariables(const size_t nel) {} 109 // For the MSD case rotations must be created in MultiSlaterFast class buildOptVariables(const std::vector<std::pair<int,int>> & rotations)110 virtual void buildOptVariables(const std::vector<std::pair<int, int>>& rotations) {} 111 // store parameters before getting destroyed by rotation. storeParamsBeforeRotation()112 virtual void storeParamsBeforeRotation() {} 113 // apply rotation to all the orbitals 114 virtual void applyRotation(const ValueMatrix_t& rot_mat, bool use_stored_copy = false) 115 { 116 std::ostringstream o; 117 o << "SPOSet::applyRotation is not implemented by " << className << std::endl; 118 APP_ABORT(o.str()); 119 } 120 /// reset parameters to the values from optimizer 121 virtual void resetParameters(const opt_variables_type& optVariables) = 0; 122 123 /// check in/out parameters to the global list of parameters used by the optimizer checkInVariables(opt_variables_type & active)124 virtual void checkInVariables(opt_variables_type& active) {} checkOutVariables(const opt_variables_type & active)125 virtual void checkOutVariables(const opt_variables_type& active) {} 126 evaluateDerivatives(ParticleSet & P,const opt_variables_type & optvars,std::vector<ValueType> & dlogpsi,std::vector<ValueType> & dhpsioverpsi,const int & FirstIndex,const int & LastIndex)127 virtual void evaluateDerivatives(ParticleSet& P, 128 const opt_variables_type& optvars, 129 std::vector<ValueType>& dlogpsi, 130 std::vector<ValueType>& dhpsioverpsi, 131 const int& FirstIndex, 132 const int& LastIndex) 133 {} 134 /** Evaluate the derivative of the optimized orbitals with respect to the parameters 135 * this is used only for MSD, to be refined for better serving both single and multi SD 136 */ evaluateDerivatives(ParticleSet & P,const opt_variables_type & optvars,std::vector<ValueType> & dlogpsi,std::vector<ValueType> & dhpsioverpsi,const ValueType & psiCurrent,const std::vector<ValueType> & Coeff,const std::vector<size_t> & C2node_up,const std::vector<size_t> & C2node_dn,const ValueVector_t & detValues_up,const ValueVector_t & detValues_dn,const GradMatrix_t & grads_up,const GradMatrix_t & grads_dn,const ValueMatrix_t & lapls_up,const ValueMatrix_t & lapls_dn,const ValueMatrix_t & M_up,const ValueMatrix_t & M_dn,const ValueMatrix_t & Minv_up,const ValueMatrix_t & Minv_dn,const GradMatrix_t & B_grad,const ValueMatrix_t & B_lapl,const std::vector<int> & detData_up,const size_t N1,const size_t N2,const size_t NP1,const size_t NP2,const std::vector<std::vector<int>> & lookup_tbl)137 virtual void evaluateDerivatives(ParticleSet& P, 138 const opt_variables_type& optvars, 139 std::vector<ValueType>& dlogpsi, 140 std::vector<ValueType>& dhpsioverpsi, 141 const ValueType& psiCurrent, 142 const std::vector<ValueType>& Coeff, 143 const std::vector<size_t>& C2node_up, 144 const std::vector<size_t>& C2node_dn, 145 const ValueVector_t& detValues_up, 146 const ValueVector_t& detValues_dn, 147 const GradMatrix_t& grads_up, 148 const GradMatrix_t& grads_dn, 149 const ValueMatrix_t& lapls_up, 150 const ValueMatrix_t& lapls_dn, 151 const ValueMatrix_t& M_up, 152 const ValueMatrix_t& M_dn, 153 const ValueMatrix_t& Minv_up, 154 const ValueMatrix_t& Minv_dn, 155 const GradMatrix_t& B_grad, 156 const ValueMatrix_t& B_lapl, 157 const std::vector<int>& detData_up, 158 const size_t N1, 159 const size_t N2, 160 const size_t NP1, 161 const size_t NP2, 162 const std::vector<std::vector<int>>& lookup_tbl) 163 {} 164 165 /** Evaluate the derivative of the optimized orbitals with respect to the parameters 166 * this is used only for MSD, to be refined for better serving both single and multi SD 167 */ evaluateDerivativesWF(ParticleSet & P,const opt_variables_type & optvars,std::vector<ValueType> & dlogpsi,const QTFull::ValueType & psiCurrent,const std::vector<ValueType> & Coeff,const std::vector<size_t> & C2node_up,const std::vector<size_t> & C2node_dn,const ValueVector_t & detValues_up,const ValueVector_t & detValues_dn,const ValueMatrix_t & M_up,const ValueMatrix_t & M_dn,const ValueMatrix_t & Minv_up,const ValueMatrix_t & Minv_dn,const std::vector<int> & detData_up,const std::vector<std::vector<int>> & lookup_tbl)168 virtual void evaluateDerivativesWF(ParticleSet& P, 169 const opt_variables_type& optvars, 170 std::vector<ValueType>& dlogpsi, 171 const QTFull::ValueType& psiCurrent, 172 const std::vector<ValueType>& Coeff, 173 const std::vector<size_t>& C2node_up, 174 const std::vector<size_t>& C2node_dn, 175 const ValueVector_t& detValues_up, 176 const ValueVector_t& detValues_dn, 177 const ValueMatrix_t& M_up, 178 const ValueMatrix_t& M_dn, 179 const ValueMatrix_t& Minv_up, 180 const ValueMatrix_t& Minv_dn, 181 const std::vector<int>& detData_up, 182 const std::vector<std::vector<int>>& lookup_tbl) 183 {} 184 185 /** set the OrbitalSetSize 186 * @param norbs number of single-particle orbitals 187 * Ye: I prefer to remove this interface in the future. SPOSet builders need to handle the size correctly. 188 * It doesn't make sense allowing to set the value at any place in the code. 189 */ 190 virtual void setOrbitalSetSize(int norbs) = 0; 191 192 /** evaluate the values of this single-particle orbital set 193 * @param P current ParticleSet 194 * @param iat active particle 195 * @param psi values of the SPO 196 */ 197 virtual void evaluateValue(const ParticleSet& P, int iat, ValueVector_t& psi) = 0; 198 199 /** evaluate determinant ratios for virtual moves, e.g., sphere move for nonlocalPP 200 * @param VP virtual particle set 201 * @param psi values of the SPO, used as a scratch space if needed 202 * @param psiinv the row of inverse slater matrix corresponding to the particle moved virtually 203 * @param ratios return determinant ratios 204 */ 205 virtual void evaluateDetRatios(const VirtualParticleSet& VP, 206 ValueVector_t& psi, 207 const ValueVector_t& psiinv, 208 std::vector<ValueType>& ratios); 209 210 /** evaluate determinant ratios for virtual moves, e.g., sphere move for nonlocalPP, of multiple walkers 211 * @param spo_list the list of SPOSet pointers in a walker batch 212 * @param vp_list a list of virtual particle sets in a walker batch 213 * @param psi_list a list of values of the SPO, used as a scratch space if needed 214 * @param invRow_ptr_list a list of pointers to the rows of inverse slater matrix corresponding to the particles moved virtually 215 * @param ratios_list a list of returning determinant ratios 216 */ 217 virtual void mw_evaluateDetRatios(const RefVectorWithLeader<SPOSet>& spo_list, 218 const RefVector<const VirtualParticleSet>& vp_list, 219 const RefVector<ValueVector_t>& psi_list, 220 const std::vector<const ValueType*>& invRow_ptr_list, 221 std::vector<std::vector<ValueType>>& ratios_list) const; 222 223 /** evaluate the values, gradients and laplacians of this single-particle orbital set 224 * @param P current ParticleSet 225 * @param iat active particle 226 * @param psi values of the SPO 227 * @param dpsi gradients of the SPO 228 * @param d2psi laplacians of the SPO 229 */ 230 virtual void evaluateVGL(const ParticleSet& P, 231 int iat, 232 ValueVector_t& psi, 233 GradVector_t& dpsi, 234 ValueVector_t& d2psi) = 0; 235 236 /** evaluate the values, gradients and laplacians and spin gradient of this single-particle orbital set 237 * @param P current ParticleSet 238 * @param iat active particle 239 * @param psi values of the SPO 240 * @param dpsi gradients of the SPO 241 * @param d2psi laplacians of the SPO 242 * @param dspin spin gradients of the SPO 243 */ 244 virtual void evaluateVGL_spin(const ParticleSet& P, 245 int iat, 246 ValueVector_t& psi, 247 GradVector_t& dpsi, 248 ValueVector_t& d2psi, 249 ValueVector_t& dspin 250 ); 251 252 /** evaluate the values, gradients and laplacians of this single-particle orbital sets of multiple walkers 253 * @param spo_list the list of SPOSet pointers in a walker batch 254 * @param P_list the list of ParticleSet pointers in a walker batch 255 * @param iat active particle 256 * @param psi_v_list the list of value vector pointers in a walker batch 257 * @param dpsi_v_list the list of gradient vector pointers in a walker batch 258 * @param d2psi_v_list the list of laplacian vector pointers in a walker batch 259 */ 260 virtual void mw_evaluateVGL(const RefVectorWithLeader<SPOSet>& spo_list, 261 const RefVectorWithLeader<ParticleSet>& P_list, 262 int iat, 263 const RefVector<ValueVector_t>& psi_v_list, 264 const RefVector<GradVector_t>& dpsi_v_list, 265 const RefVector<ValueVector_t>& d2psi_v_list) const; 266 267 /** evaluate the values, gradients and laplacians of this single-particle orbital sets 268 * and determinant ratio and grads of multiple walkers 269 * @param spo_list the list of SPOSet pointers in a walker batch 270 * @param P_list the list of ParticleSet pointers in a walker batch 271 * @param iat active particle 272 * @param phi_vgl_v orbital values, gradients and laplacians of all the walkers 273 * @param psi_ratio_grads_v determinant ratio and grads of all the walkers 274 */ 275 virtual void mw_evaluateVGLandDetRatioGrads(const RefVectorWithLeader<SPOSet>& spo_list, 276 const RefVectorWithLeader<ParticleSet>& P_list, 277 int iat, 278 const std::vector<const ValueType*>& invRow_ptr_list, 279 VGLVector_t& phi_vgl_v, 280 std::vector<ValueType>& ratios, 281 std::vector<GradType>& grads) const; 282 283 /** evaluate the values, gradients and hessians of this single-particle orbital set 284 * @param P current ParticleSet 285 * @param iat active particle 286 * @param psi values of the SPO 287 * @param dpsi gradients of the SPO 288 * @param grad_grad_psi hessians of the SPO 289 */ 290 virtual void evaluateVGH(const ParticleSet& P, 291 int iat, 292 ValueVector_t& psi, 293 GradVector_t& dpsi, 294 HessVector_t& grad_grad_psi); 295 296 /** evaluate the values, gradients, hessians, and grad hessians of this single-particle orbital set 297 * @param P current ParticleSet 298 * @param iat active particle 299 * @param psi values of the SPO 300 * @param dpsi gradients of the SPO 301 * @param grad_grad_psi hessians of the SPO 302 * @param grad_grad_grad_psi grad hessians of the SPO 303 */ 304 virtual void evaluateVGHGH(const ParticleSet& P, 305 int iat, 306 ValueVector_t& psi, 307 GradVector_t& dpsi, 308 HessVector_t& grad_grad_psi, 309 GGGVector_t& grad_grad_grad_psi); 310 311 /** evaluate the values of this single-particle orbital set 312 * @param P current ParticleSet 313 * @param iat active particle 314 * @param psi values of the SPO 315 */ 316 virtual void evaluate_spin(const ParticleSet& P, int iat, ValueVector_t& psi, ValueVector_t& dpsi); 317 318 /** evaluate the third derivatives of this single-particle orbital set 319 * @param P current ParticleSet 320 * @param first first particle 321 * @param last last particle 322 * @param grad_grad_grad_logdet third derivatives of the SPO 323 */ 324 virtual void evaluateThirdDeriv(const ParticleSet& P, int first, int last, GGGMatrix_t& grad_grad_grad_logdet); 325 326 /** evaluate the values, gradients and laplacians of this single-particle orbital for [first,last) particles 327 * @param P current ParticleSet 328 * @param first starting index of the particles 329 * @param last ending index of the particles 330 * @param logdet determinant matrix to be inverted 331 * @param dlogdet gradients 332 * @param d2logdet laplacians 333 * 334 */ 335 virtual void evaluate_notranspose(const ParticleSet& P, 336 int first, 337 int last, 338 ValueMatrix_t& logdet, 339 GradMatrix_t& dlogdet, 340 ValueMatrix_t& d2logdet) = 0; 341 342 virtual void mw_evaluate_notranspose(const RefVectorWithLeader<SPOSet>& spo_list, 343 const RefVectorWithLeader<ParticleSet>& P_list, 344 int first, 345 int last, 346 const RefVector<ValueMatrix_t>& logdet_list, 347 const RefVector<GradMatrix_t>& dlogdet_list, 348 const RefVector<ValueMatrix_t>& d2logdet_list) const; 349 350 /** evaluate the values, gradients and hessians of this single-particle orbital for [first,last) particles 351 * @param P current ParticleSet 352 * @param first starting index of the particles 353 * @param last ending index of the particles 354 * @param logdet determinant matrix to be inverted 355 * @param dlogdet gradients 356 * @param grad_grad_logdet hessians 357 * 358 */ 359 virtual void evaluate_notranspose(const ParticleSet& P, 360 int first, 361 int last, 362 ValueMatrix_t& logdet, 363 GradMatrix_t& dlogdet, 364 HessMatrix_t& grad_grad_logdet); 365 366 /** evaluate the values, gradients, hessians and third derivatives of this single-particle orbital for [first,last) particles 367 * @param P current ParticleSet 368 * @param first starting index of the particles 369 * @param last ending index of the particles 370 * @param logdet determinant matrix to be inverted 371 * @param dlogdet gradients 372 * @param grad_grad_logdet hessians 373 * @param grad_grad_grad_logdet third derivatives 374 * 375 */ 376 virtual void evaluate_notranspose(const ParticleSet& P, 377 int first, 378 int last, 379 ValueMatrix_t& logdet, 380 GradMatrix_t& dlogdet, 381 HessMatrix_t& grad_grad_logdet, 382 GGGMatrix_t& grad_grad_grad_logdet); 383 384 /** evaluate the gradients of this single-particle orbital 385 * for [first,last) target particles with respect to the given source particle 386 * @param P current ParticleSet 387 * @param first starting index of the particles 388 * @param last ending index of the particles 389 * @param iat_src source particle index 390 * @param gradphi gradients 391 * 392 */ 393 virtual void evaluateGradSource(const ParticleSet& P, 394 int first, 395 int last, 396 const ParticleSet& source, 397 int iat_src, 398 GradMatrix_t& gradphi); 399 400 /** evaluate the gradients of values, gradients, laplacians of this single-particle orbital 401 * for [first,last) target particles with respect to the given source particle 402 * @param P current ParticleSet 403 * @param first starting index of the particles 404 * @param last ending index of the particles 405 * @param iat_src source particle index 406 * @param gradphi gradients of values 407 * @param grad_grad_phi gradients of gradients 408 * @param grad_lapl_phi gradients of laplacians 409 * 410 */ 411 virtual void evaluateGradSource(const ParticleSet& P, 412 int first, 413 int last, 414 const ParticleSet& source, 415 int iat_src, 416 GradMatrix_t& grad_phi, 417 HessMatrix_t& grad_grad_phi, 418 GradMatrix_t& grad_lapl_phi); 419 420 /** access the k point related to the given orbital */ get_k(int orb)421 virtual PosType get_k(int orb) { return PosType(); } 422 423 /** initialize a shared resource and hand it to collection 424 */ createResource(ResourceCollection & collection)425 virtual void createResource(ResourceCollection& collection) const {} 426 427 /** acquire a shared resource from collection 428 */ acquireResource(ResourceCollection & collection)429 virtual void acquireResource(ResourceCollection& collection) {} 430 431 /** return a shared resource to collection 432 */ releaseResource(ResourceCollection & collection)433 virtual void releaseResource(ResourceCollection& collection) {} 434 435 /** make a clone of itself 436 * every derived class must implement this to have threading working correctly. 437 */ 438 virtual SPOSet* makeClone() const; 439 440 /** Used only by cusp correction in AOS LCAO. 441 * Ye: the SoA LCAO moves all this responsibility to the builder. 442 * This interface should be removed with AoS. 443 */ transformSPOSet()444 virtual bool transformSPOSet() { return true; } 445 446 /** finalize the construction of SPOSet 447 * 448 * for example, classes serving accelerators may need to transfer data from host to device 449 * after the host side objects are built. 450 */ finalizeConstruction()451 virtual void finalizeConstruction() {} 452 453 /// set object name setName(const std::string & name)454 void setName(const std::string& name) { myName = name; } 455 /// return object name getName()456 const std::string& getName() const { return myName; } 457 458 #ifdef QMC_CUDA 459 /** Evaluate the SPO value at an explicit position. 460 * Ye: This is used only for debugging the CUDA code and should be removed. 461 */ 462 virtual void evaluate(const ParticleSet& P, PosType& r, ValueVector_t& psi); 463 464 using CTS = CUDAGlobalTypes; 465 466 ////////////////////////////////////////// 467 // Walker-parallel vectorized functions // 468 ////////////////////////////////////////// reserve(PointerPool<gpu::device_vector<CTS::ValueType>> & pool)469 virtual void reserve(PointerPool<gpu::device_vector<CTS::ValueType>>& pool) {} 470 471 virtual void evaluate(std::vector<Walker_t*>& walkers, int iat, gpu::device_vector<CTS::ValueType*>& phi); 472 473 virtual void evaluate(std::vector<Walker_t*>& walkers, 474 std::vector<PosType>& new_pos, 475 gpu::device_vector<CTS::ValueType*>& phi); 476 477 virtual void evaluate(std::vector<Walker_t*>& walkers, 478 std::vector<PosType>& new_pos, 479 gpu::device_vector<CTS::ValueType*>& phi, 480 gpu::device_vector<CTS::ValueType*>& grad_lapl_list, 481 int row_stride); 482 483 virtual void evaluate(std::vector<Walker_t*>& walkers, 484 std::vector<PosType>& new_pos, 485 gpu::device_vector<CTS::ValueType*>& phi, 486 gpu::device_vector<CTS::ValueType*>& grad_lapl_list, 487 int row_stride, 488 int k, 489 bool klinear); 490 491 virtual void evaluate(std::vector<PosType>& pos, gpu::device_vector<CTS::RealType*>& phi); 492 virtual void evaluate(std::vector<PosType>& pos, gpu::device_vector<CTS::ComplexType*>& phi); 493 #endif 494 495 protected: 496 ///true, if the derived class uses OpenMP offload and statisfies a few assumptions 497 const bool useOMPoffload; 498 ///true, if the derived class has non-zero ionic derivatives. 499 const bool ionDerivs; 500 ///true if SPO is optimizable 501 const bool Optimizable; 502 ///number of Single-particle orbitals 503 IndexType OrbitalSetSize; 504 /// Optimizable variables 505 opt_variables_type myVars; 506 ///name of the class 507 std::string className; 508 /// name of the object, unique identifier 509 std::string myName; 510 }; 511 512 typedef SPOSet* SPOSetPtr; 513 514 } // namespace qmcplusplus 515 #endif 516