QMCPACK
SplineC2COMPTarget.h
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) 2020 QMCPACK developers.
6 //
7 // File developed by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
8 //
9 // File created by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 /** @file SplineC2COMPTarget.h
14  *
15  * class to handle complex splines to complex orbitals with splines of arbitrary precision
16  * splines storage and computation is offloaded to accelerators using OpenMP target
17  */
18 #ifndef QMCPLUSPLUS_SPLINE_C2C_OMPTARGET_H
19 #define QMCPLUSPLUS_SPLINE_C2C_OMPTARGET_H
20 
21 #include <memory>
24 #include "spline2/MultiBspline.hpp"
26 #include "Utilities/FairDivide.h"
27 #include "Utilities/TimerManager.h"
28 #include <ResourceHandle.h>
30 
31 namespace qmcplusplus
32 {
33 /** class to match std::complex<ST> spline with BsplineSet::ValueType (complex) SPOs with OpenMP offload
34  * @tparam ST precision of spline
35  *
36  * Requires temporage storage and multiplication of phase vectors
37  * The internal storage of complex spline coefficients uses double sized real arrays of ST type, aligned and padded.
38  * All the output orbitals are complex.
39  */
40 template<typename ST>
42 {
43 public:
44  using SplineType = typename bspline_traits<ST, 3>::SplineType;
45  using BCType = typename bspline_traits<ST, 3>::BCType;
46  using DataType = ST;
48  using SingleSplineType = UBspline_3d_d;
49  // types for evaluation results
50  using ComplexT = typename BsplineSet::ValueType;
55 
60 
61  template<typename DT>
63  template<typename DT>
65 
66 private:
67  /// timer for offload portion
69  ///primitive cell
71  ///\f$GGt=G^t G \f$, transformation for tensor in LatticeUnit to CartesianUnit, e.g. Hessian
73  ///multi bspline set
74  std::shared_ptr<MultiBspline<ST, OffloadAllocator<ST>, OffloadAllocator<SplineType>>> SplineInst;
75 
76  std::shared_ptr<OffloadVector<ST>> mKK;
77  std::shared_ptr<OffloadPosVector<ST>> myKcart;
78  std::shared_ptr<OffloadVector<ST>> GGt_offload;
79  std::shared_ptr<OffloadVector<ST>> PrimLattice_G_offload;
80 
82 
83  ///team private ratios for reduction, numVP x numTeams
85  ///offload scratch space, dynamically resized to the maximal need
87  ///result scratch space, dynamically resized to the maximal need
89  ///psiinv and position scratch space, used to avoid allocation on the fly and faster transfer
91  ///position scratch space, used to avoid allocation on the fly and faster transfer
93 
97  const RefVector<ValueVector>& psi_v_list,
98  const RefVector<GradVector>& dpsi_v_list,
99  const RefVector<ValueVector>& d2psi_v_list) const;
100 
101 protected:
102  /// intermediate result vectors
108 
109 public:
110  SplineC2COMPTarget(const std::string& my_name)
111  : BsplineSet(my_name),
112  offload_timer_(createGlobalTimer("SplineC2COMPTarget::offload", timer_level_fine)),
113  GGt_offload(std::make_shared<OffloadVector<ST>>(9)),
114  PrimLattice_G_offload(std::make_shared<OffloadVector<ST>>(9))
115  {}
116 
118 
119  virtual std::string getClassName() const override { return "SplineC2COMPTarget"; }
120  virtual std::string getKeyword() const override { return "SplineC2C"; }
121  bool isComplex() const override { return true; };
122  virtual bool isOMPoffload() const override { return true; }
123 
124  void createResource(ResourceCollection& collection) const override
125  {
126  auto resource_index = collection.addResource(std::make_unique<SplineOMPTargetMultiWalkerMem<ST, ComplexT>>());
127  }
128 
129  void acquireResource(ResourceCollection& collection, const RefVectorWithLeader<SPOSet>& spo_list) const override
130  {
131  assert(this == &spo_list.getLeader());
132  auto& phi_leader = spo_list.getCastedLeader<SplineC2COMPTarget<ST>>();
134  }
135 
136  void releaseResource(ResourceCollection& collection, const RefVectorWithLeader<SPOSet>& spo_list) const override
137  {
138  assert(this == &spo_list.getLeader());
139  auto& phi_leader = spo_list.getCastedLeader<SplineC2COMPTarget<ST>>();
140  collection.takebackResource(phi_leader.mw_mem_handle_);
141  }
142 
143  std::unique_ptr<SPOSet> makeClone() const override { return std::make_unique<SplineC2COMPTarget>(*this); }
144 
145  inline void resizeStorage(size_t n, size_t nvals)
146  {
147  init_base(n);
148  size_t npad = getAlignedSize<ST>(2 * n);
149  myV.resize(npad);
150  myG.resize(npad);
151  myL.resize(npad);
152  myH.resize(npad);
153  mygH.resize(npad);
154  }
155 
156  void bcast_tables(Communicate* comm) { chunked_bcast(comm, SplineInst->getSplinePtr()); }
157 
159  {
160  if (comm->size() == 1)
161  return;
162  const int Nbands = kPoints.size();
163  const int Nbandgroups = comm->size();
164  offset.resize(Nbandgroups + 1, 0);
165  FairDivideLow(Nbands, Nbandgroups, offset);
166 
167  for (size_t ib = 0; ib < offset.size(); ib++)
168  offset[ib] *= 2;
169  gatherv(comm, SplineInst->getSplinePtr(), SplineInst->getSplinePtr()->z_stride, offset);
170  }
171 
172  template<typename GT, typename BCT>
173  void create_spline(GT& xyz_g, BCT& xyz_bc)
174  {
175  resize_kpoints();
176  SplineInst = std::make_shared<MultiBspline<ST, OffloadAllocator<ST>, OffloadAllocator<SplineType>>>();
177  SplineInst->create(xyz_g, xyz_bc, myV.size());
178 
179  app_log() << "MEMORY " << SplineInst->sizeInByte() / (1 << 20) << " MB allocated "
180  << "for the coefficients in 3D spline orbital representation" << std::endl;
181  }
182 
183  /// this routine can not be called from threaded region
184  void finalizeConstruction() override
185  {
186  // map the SplineInst->getSplinePtr() structure to GPU
187  auto* MultiSpline = SplineInst->getSplinePtr();
188  auto* restrict coefs = MultiSpline->coefs;
189  // attach pointers on the device to achieve deep copy
190  PRAGMA_OFFLOAD("omp target map(always, to: MultiSpline[0:1], coefs[0:MultiSpline->coefs_size])")
191  {
192  MultiSpline->coefs = coefs;
193  }
194 
195  // transfer static data to GPU
196  auto* mKK_ptr = mKK->data();
197  PRAGMA_OFFLOAD("omp target update to(mKK_ptr[0:mKK->size()])")
198  auto* myKcart_ptr = myKcart->data();
199  PRAGMA_OFFLOAD("omp target update to(myKcart_ptr[0:myKcart->capacity()*3])")
200  for (uint32_t i = 0; i < 9; i++)
201  {
202  (*GGt_offload)[i] = GGt[i];
203  (*PrimLattice_G_offload)[i] = PrimLattice.G[i];
204  }
205  auto* PrimLattice_G_ptr = PrimLattice_G_offload->data();
206  PRAGMA_OFFLOAD("omp target update to(PrimLattice_G_ptr[0:9])")
207  auto* GGt_ptr = GGt_offload->data();
208  PRAGMA_OFFLOAD("omp target update to(GGt_ptr[0:9])")
209  }
210 
211  inline void flush_zero() { SplineInst->flush_zero(); }
212 
213  /** remap kPoints to pack the double copy */
214  inline void resize_kpoints()
215  {
216  const size_t nk = kPoints.size();
217  mKK = std::make_shared<OffloadVector<ST>>(nk);
218  myKcart = std::make_shared<OffloadPosVector<ST>>(nk);
219  for (size_t i = 0; i < nk; ++i)
220  {
221  (*mKK)[i] = -dot(kPoints[i], kPoints[i]);
222  (*myKcart)(i) = kPoints[i];
223  }
224  }
225 
226  void set_spline(SingleSplineType* spline_r, SingleSplineType* spline_i, int twist, int ispline, int level);
227 
228  bool read_splines(hdf_archive& h5f);
229 
230  bool write_splines(hdf_archive& h5f);
231 
232  void assign_v(const PointType& r, const vContainer_type& myV, ValueVector& psi, int first, int last) const;
233 
234  virtual void evaluateValue(const ParticleSet& P, const int iat, ValueVector& psi) override;
235 
236  virtual void evaluateDetRatios(const VirtualParticleSet& VP,
237  ValueVector& psi,
238  const ValueVector& psiinv,
239  std::vector<ValueType>& ratios) override;
240 
241  virtual void mw_evaluateDetRatios(const RefVectorWithLeader<SPOSet>& spo_list,
243  const RefVector<ValueVector>& psi_list,
244  const std::vector<const ValueType*>& invRow_ptr_list,
245  std::vector<std::vector<ValueType>>& ratios_list) const override;
246 
247  /** assign_vgl_from_l can be used when myL is precomputed and myV,myG,myL in cartesian
248  */
249  void assign_vgl_from_l(const PointType& r, ValueVector& psi, GradVector& dpsi, ValueVector& d2psi);
250 
251  virtual void evaluateVGL(const ParticleSet& P,
252  const int iat,
253  ValueVector& psi,
254  GradVector& dpsi,
255  ValueVector& d2psi) override;
256 
257  virtual void mw_evaluateVGL(const RefVectorWithLeader<SPOSet>& sa_list,
258  const RefVectorWithLeader<ParticleSet>& P_list,
259  int iat,
260  const RefVector<ValueVector>& psi_v_list,
261  const RefVector<GradVector>& dpsi_v_list,
262  const RefVector<ValueVector>& d2psi_v_list) const override;
263 
264  virtual void mw_evaluateVGLandDetRatioGrads(const RefVectorWithLeader<SPOSet>& spo_list,
265  const RefVectorWithLeader<ParticleSet>& P_list,
266  int iat,
267  const std::vector<const ValueType*>& invRow_ptr_list,
268  OffloadMWVGLArray& phi_vgl_v,
269  std::vector<ValueType>& ratios,
270  std::vector<GradType>& grads) const override;
271 
272  void assign_vgh(const PointType& r,
273  ValueVector& psi,
274  GradVector& dpsi,
275  HessVector& grad_grad_psi,
276  int first,
277  int last) const;
278 
279  virtual void evaluateVGH(const ParticleSet& P,
280  const int iat,
281  ValueVector& psi,
282  GradVector& dpsi,
283  HessVector& grad_grad_psi) override;
284 
285  void assign_vghgh(const PointType& r,
286  ValueVector& psi,
287  GradVector& dpsi,
288  HessVector& grad_grad_psi,
289  GGGVector& grad_grad_grad_psi,
290  int first = 0,
291  int last = -1) const;
292 
293  virtual void evaluateVGHGH(const ParticleSet& P,
294  const int iat,
295  ValueVector& psi,
296  GradVector& dpsi,
297  HessVector& grad_grad_psi,
298  GGGVector& grad_grad_grad_psi) override;
299 
300  virtual void evaluate_notranspose(const ParticleSet& P,
301  int first,
302  int last,
303  ValueMatrix& logdet,
304  GradMatrix& dlogdet,
305  ValueMatrix& d2logdet) override;
306 
307  template<class BSPLINESPO>
308  friend class SplineSetReader;
309  friend struct BsplineReader;
310 };
311 
312 extern template class SplineC2COMPTarget<float>;
313 extern template class SplineC2COMPTarget<double>;
314 
315 } // namespace qmcplusplus
316 #endif
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
OrbitalSetTraits< ValueType >::HessVector HessVector
Definition: SPOSet.h:53
void create_spline(GT &xyz_g, BCT &xyz_bc)
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
virtual void evaluateVGL(const ParticleSet &P, const int iat, ValueVector &psi, GradVector &dpsi, ValueVector &d2psi) override
evaluate the values, gradients and laplacians of this single-particle orbital set ...
size_t addResource(std::unique_ptr< Resource > &&res, bool noprint=false)
void takebackResource(ResourceHandle< RS > &res_handle)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
timer_manager class.
BsplineSet is the base class for SplineC2C, SplineC2R, SplineR2R.
Definition: BsplineSet.h:34
virtual void evaluateValue(const ParticleSet &P, const int iat, ValueVector &psi) override
evaluate the values of this single-particle orbital set
void gather_tables(Communicate *comm)
std::ostream & app_log()
Definition: OutputManager.h:65
ResourceHandle< SplineOMPTargetMultiWalkerMem< ST, ComplexT > > mw_mem_handle_
ResourceHandle manages the temporary resource referenced from a collection.
A ParticleSet that handles virtual moves of a selected particle of a given physical ParticleSet Virtu...
Soa Container for D-dim vectors.
Matrix< ComplexT, OffloadPinnedAllocator< ComplexT > > ratios_private
team private ratios for reduction, numVP x numTeams
OrbitalSetTraits< ValueType >::ValueMatrix ValueMatrix
Definition: SPOSet.h:50
virtual std::string getClassName() const override
return class name
class to handle hdf file
Definition: hdf_archive.h:51
bool write_splines(hdf_archive &h5f)
Timer accumulates time and call counts.
Definition: NewTimer.h:135
Tensor_t G
Reciprocal unit vectors. G(j,i) i=vector and j=x,y,z.
void resizeStorage(size_t n, size_t nvals)
virtual void evaluateVGH(const ParticleSet &P, const int iat, ValueVector &psi, GradVector &dpsi, HessVector &grad_grad_psi) override
evaluate the values, gradients and hessians of this single-particle orbital set
OrbitalSetTraits< ValueType >::ValueVector ValueVector
int size() const
return the number of tasks
Definition: Communicate.h:118
class to match std::complex<ST> spline with BsplineSet::ValueType (complex) SPOs with OpenMP offload ...
std::shared_ptr< MultiBspline< ST, OffloadAllocator< ST >, OffloadAllocator< SplineType > > > SplineInst
multi bspline set
void FairDivideLow(int ntot, int npart, IV &adist)
partition ntot elements among npart
Definition: FairDivide.h:114
virtual void mw_evaluateVGLandDetRatioGrads(const RefVectorWithLeader< SPOSet > &spo_list, const RefVectorWithLeader< ParticleSet > &P_list, int iat, const std::vector< const ValueType *> &invRow_ptr_list, OffloadMWVGLArray &phi_vgl_v, std::vector< ValueType > &ratios, std::vector< GradType > &grads) const override
evaluate the values, gradients and laplacians of this single-particle orbital sets and determinant ra...
void evaluateVGLMultiPos(const Vector< ST, OffloadPinnedAllocator< ST >> &multi_pos_copy, Vector< ST, OffloadPinnedAllocator< ST >> &offload_scratch, Vector< ComplexT, OffloadPinnedAllocator< ComplexT >> &results_scratch, const RefVector< ValueVector > &psi_v_list, const RefVector< GradVector > &dpsi_v_list, const RefVector< ValueVector > &d2psi_v_list) const
OrbitalSetTraits< ValueType >::GradMatrix GradMatrix
Definition: SPOSet.h:52
Wrapping information on parallelism.
Definition: Communicate.h:68
Each SplineC2X needs a reader derived from BsplineReader.
Definition: BsplineReader.h:39
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
General SplineSetReader to handle any unitcell.
std::shared_ptr< OffloadVector< ST > > PrimLattice_G_offload
std::vector< int > offset
band offsets used for communication
Definition: BsplineSet.h:56
typename bspline_traits< ST, 3 >::SplineType SplineType
A collection of functions for dividing fairly.
size_type size() const
return the current size
Definition: OhmmsVector.h:162
Array< ValueType, 3, OffloadPinnedAllocator< ValueType > > OffloadMWVGLArray
Definition: SPOSet.h:58
SplineC2COMPTarget(const std::string &my_name)
void createResource(ResourceCollection &collection) const override
initialize a shared resource and hand it to collection
QTBase::ValueType ValueType
Definition: Configuration.h:60
std::shared_ptr< OffloadVector< ST > > GGt_offload
void releaseResource(ResourceCollection &collection, const RefVectorWithLeader< SPOSet > &spo_list) const override
return a shared resource to collection
Vector< ComplexT, OffloadPinnedAllocator< ComplexT > > psiinv_pos_copy
psiinv and position scratch space, used to avoid allocation on the fly and faster transfer ...
std::shared_ptr< OffloadVector< ST > > mKK
OrbitalSetTraits< ValueType >::ValueVector ValueVector
Definition: SPOSet.h:49
virtual void mw_evaluateDetRatios(const RefVectorWithLeader< SPOSet > &spo_list, const RefVectorWithLeader< const VirtualParticleSet > &vp_list, const RefVector< ValueVector > &psi_list, const std::vector< const ValueType *> &invRow_ptr_list, std::vector< std::vector< ValueType >> &ratios_list) const override
evaluate determinant ratios for virtual moves, e.g., sphere move for nonlocalPP, of multiple walkers ...
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
void assign_vgh(const PointType &r, ValueVector &psi, GradVector &dpsi, HessVector &grad_grad_psi, int first, int last) const
BsplineSet is a SPOSet derived class and serves as a base class for B-spline SPO C2C/C2R/R2R implemen...
void acquireResource(ResourceCollection &collection, const RefVectorWithLeader< SPOSet > &spo_list) const override
acquire a shared resource from collection
void assign_vghgh(const PointType &r, ValueVector &psi, GradVector &dpsi, HessVector &grad_grad_psi, GGGVector &grad_grad_grad_psi, int first=0, int last=-1) const
OMPallocator is an allocator with fused device and dualspace allocator functionality.
Vector< ST, aligned_allocator< ST > > vContainer_type
typename BsplineSet::ValueType ComplexT
CrystalLattice< ST, 3 > PrimLattice
primitive cell
void assign_v(const PointType &r, const vContainer_type &myV, ValueVector &psi, int first, int last) const
virtual bool isOMPoffload() const override
Query if this SPOSet uses OpenMP offload.
virtual void evaluate_notranspose(const ParticleSet &P, int first, int last, ValueMatrix &logdet, GradMatrix &dlogdet, ValueMatrix &d2logdet) override
evaluate the values, gradients and laplacians of this single-particle orbital for [first...
vContainer_type myV
intermediate result vectors
std::vector< std::reference_wrapper< T > > RefVector
virtual void mw_evaluateVGL(const RefVectorWithLeader< SPOSet > &sa_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) const override
evaluate the values, gradients and laplacians of this single-particle orbital sets of multiple walker...
bool read_splines(hdf_archive &h5f)
std::shared_ptr< OffloadPosVector< ST > > myKcart
OrbitalSetTraits< ValueType >::GradHessVector GGGVector
Definition: SPOSet.h:55
OrbitalSetTraits< ValueType >::GradVector GradVector
Definition: SPOSet.h:51
void assign_vgl_from_l(const PointType &r, ValueVector &psi, GradVector &dpsi, ValueVector &d2psi)
assign_vgl_from_l can be used when myL is precomputed and myV,myG,myL in cartesian ...
NewTimer & offload_timer_
timer for offload portion
std::unique_ptr< SPOSet > makeClone() const override
make a clone of itself every derived class must implement this to have threading working correctly...
virtual void evaluateDetRatios(const VirtualParticleSet &VP, ValueVector &psi, const ValueVector &psiinv, std::vector< ValueType > &ratios) override
evaluate determinant ratios for virtual moves, e.g., sphere move for nonlocalPP
void init_base(int n)
Definition: BsplineSet.h:66
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
virtual void evaluateVGHGH(const ParticleSet &P, const int iat, ValueVector &psi, GradVector &dpsi, HessVector &grad_grad_psi, GGGVector &grad_grad_grad_psi) override
evaluate the values, gradients, hessians, and grad hessians of this single-particle orbital set ...
ResourceHandle< RS > lendResource()
Vector< ST, OffloadPinnedAllocator< ST > > multi_pos_copy
position scratch space, used to avoid allocation on the fly and faster transfer
void resize(size_type n)
resize myData
Vector< ST, OffloadPinnedAllocator< ST > > offload_scratch
offload scratch space, dynamically resized to the maximal need
void resize_kpoints()
remap kPoints to pack the double copy
typename bspline_traits< ST, 3 >::BCType BCType
void gatherv(T *sb, T *rb, int n, IT &counts, IT &displ, int dest)
Tensor< ST, 3 > GGt
, transformation for tensor in LatticeUnit to CartesianUnit, e.g. Hessian
void set_spline(SingleSplineType *spline_r, SingleSplineType *spline_i, int twist, int ispline, int level)
void finalizeConstruction() override
this routine can not be called from threaded region
Vector< ComplexT, OffloadPinnedAllocator< ComplexT > > results_scratch
result scratch space, dynamically resized to the maximal need
void bcast_tables(Communicate *comm)
std::vector< SPOSet::PosType > kPoints
kpoints for each unique orbitals.
Definition: BsplineSet.h:52
virtual std::string getKeyword() const override