QMCPACK
StructFact.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) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Bryan Clark, bclark@Princeton.edu, Princeton University
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 //
12 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
13 //////////////////////////////////////////////////////////////////////////////////////
14 
15 
16 #include "StructFact.h"
17 #include "CPU/math.hpp"
18 #include "CPU/e2iphi.h"
19 #include "CPU/SIMD/vmath.hpp"
20 #include "CPU/BLAS.hpp"
21 #include "Utilities/qmc_common.h"
24 #include "LRCoulombSingleton.h"
25 
26 namespace qmcplusplus
27 {
28 //Constructor - pass arguments to k_lists_' constructor
30  : SuperCellEnum(SUPERCELL_BULK),
31  k_lists_(k_lists),
32  StorePerParticle(false),
33  update_all_timer_(createGlobalTimer("StructFact::update_all_part", timer_level_fine))
34 {
36  {
37  app_log() << " Setting StructFact::SuperCellEnum=SUPERCELL_SLAB " << std::endl;
39  }
40 }
41 
42 //Destructor
43 StructFact::~StructFact() = default;
44 
45 void StructFact::resize(int nkpts, int num_species, int num_ptcls)
46 {
47  rhok_r.resize(num_species, nkpts);
48  rhok_i.resize(num_species, nkpts);
49  if (StorePerParticle)
50  {
51  eikr_r.resize(num_ptcls, nkpts);
52  eikr_i.resize(num_ptcls, nkpts);
53  }
54 }
55 
56 
58 {
60  computeRhok(P);
61 }
62 
65  SKMultiWalkerMem& mw_mem)
66 {
67  auto& sk_leader = sk_list.getLeader();
68  auto& p_leader = p_list.getLeader();
69  ScopedTimer local(sk_leader.update_all_timer_);
70  if (p_leader.getCoordinates().getKind() != DynamicCoordinateKind::DC_POS_OFFLOAD || sk_leader.StorePerParticle)
71  for (int iw = 0; iw < sk_list.size(); iw++)
72  sk_list[iw].computeRhok(p_list[iw]);
73  else
74  {
75  const size_t nw = p_list.size();
76  const size_t num_species = p_leader.groups();
77  const auto& kpts_cart = sk_leader.k_lists_.get_kpts_cart_soa();
78  const size_t nk = sk_leader.k_lists_.numk;
79  const size_t nk_padded = kpts_cart.capacity();
80 
81  auto& coordinates_leader = static_cast<const RealSpacePositionsOMPTarget&>(p_leader.getCoordinates());
82  auto& mw_rsoa_dev_ptrs = coordinates_leader.getMultiWalkerRSoADevicePtrs();
83  const size_t np_padded = p_leader.getCoordinates().getAllParticlePos().capacity();
84 
85  constexpr size_t cplx_stride = 2;
86  mw_mem.nw_rhok.resize(nw * num_species * cplx_stride, nk_padded);
87 
88  // make the compute over nk by blocks
89  constexpr size_t kblock_size = 512;
90  const size_t num_kblocks = (nk + kblock_size) / kblock_size;
91 
92  auto* mw_rsoa_ptr = mw_rsoa_dev_ptrs.data();
93  auto* kpts_cart_ptr = kpts_cart.data();
94  auto* mw_rhok_ptr = mw_mem.nw_rhok.data();
95  auto* group_offsets = p_leader.get_group_offsets().data();
96 
97  PRAGMA_OFFLOAD("omp target teams distribute collapse(2) map(always, from : mw_rhok_ptr[:mw_mem.nw_rhok.size()])")
98  for (int iw = 0; iw < nw; iw++)
99  for (int ib = 0; ib < num_kblocks; ib++)
100  {
101  const size_t offset = ib * kblock_size;
102  const size_t this_block_size = omptarget::min(kblock_size, nk - offset);
103  const auto* rsoa_ptr = mw_rsoa_ptr[iw];
104 
105  PRAGMA_OFFLOAD("omp parallel for")
106  for (int ik = 0; ik < this_block_size; ik++)
107  for (int is = 0; is < num_species; is++)
108  {
109  RealType rhok_r(0), rhok_i(0);
110 
111  for (int ip = group_offsets[is]; ip < group_offsets[is + 1]; ip++)
112  {
113  RealType s, c, phase(0);
114  for (int idim = 0; idim < DIM; idim++)
115  phase += kpts_cart_ptr[ik + offset + nk_padded * idim] * rsoa_ptr[ip + idim * np_padded];
116  omptarget::sincos(phase, &s, &c);
117  rhok_r += c;
118  rhok_i += s;
119  }
120 
121  mw_rhok_ptr[(iw * num_species + is) * cplx_stride * nk_padded + offset + ik] = rhok_r;
122  mw_rhok_ptr[(iw * num_species + is) * cplx_stride * nk_padded + nk_padded + offset + ik] = rhok_i;
123  }
124  }
125 
126  for (int iw = 0; iw < nw; iw++)
127  for (int is = 0; is < num_species; is++)
128  {
129  std::copy_n(mw_mem.nw_rhok[(iw * num_species + is) * cplx_stride], nk, sk_list[iw].rhok_r[is]);
130  std::copy_n(mw_mem.nw_rhok[(iw * num_species + is) * cplx_stride + 1], nk, sk_list[iw].rhok_i[is]);
131  }
132  }
133 }
134 
135 
136 /** evaluate rok per species, eikr per particle
137  */
139 {
140  const size_t num_ptcls = P.getTotalNum();
141  const size_t num_species = P.groups();
142  const size_t nk = k_lists_.numk;
143  resize(nk, num_species, num_ptcls);
144 
145  rhok_r = 0.0;
146  rhok_i = 0.0;
147  if (StorePerParticle)
148  {
149  // save per particle and species value
150  for (int i = 0; i < num_ptcls; ++i)
151  {
152  const auto& pos = P.R[i];
153  auto* restrict eikr_r_ptr = eikr_r[i];
154  auto* restrict eikr_i_ptr = eikr_i[i];
155  auto* restrict rhok_r_ptr = rhok_r[P.getGroupID(i)];
156  auto* restrict rhok_i_ptr = rhok_i[P.getGroupID(i)];
157 #pragma omp simd
158  for (int ki = 0; ki < nk; ki++)
159  {
160  qmcplusplus::sincos(dot(k_lists_.kpts_cart[ki], pos), &eikr_i_ptr[ki], &eikr_r_ptr[ki]);
161  rhok_r_ptr[ki] += eikr_r_ptr[ki];
162  rhok_i_ptr[ki] += eikr_i_ptr[ki];
163  }
164  }
165  }
166  else
167  {
168  // save per species value
169  for (int i = 0; i < num_ptcls; ++i)
170  {
171  const auto& pos = P.R[i];
172  auto* restrict rhok_r_ptr = rhok_r[P.getGroupID(i)];
173  auto* restrict rhok_i_ptr = rhok_i[P.getGroupID(i)];
174 #if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER)
175 #pragma omp simd
176  for (int ki = 0; ki < nk; ki++)
177  {
178  RealType s, c;
179  qmcplusplus::sincos(dot(k_lists_.kpts_cart[ki], pos), &s, &c);
180  rhok_r_ptr[ki] += c;
181  rhok_i_ptr[ki] += s;
182  }
183 #else
184  // make the compute over nk by blocks
185  constexpr size_t kblock_size = 512;
186  const size_t num_kblocks = (nk + kblock_size) / kblock_size;
187  RealType phiV[kblock_size], eikr_r_temp[kblock_size], eikr_i_temp[kblock_size];
188 
189  for (int ib = 0; ib < num_kblocks; ib++)
190  {
191  const size_t offset = ib * kblock_size;
192  const size_t this_block_size = std::min(kblock_size, nk - offset);
193  for (int ki = 0; ki < this_block_size; ki++)
194  phiV[ki] = dot(k_lists_.kpts_cart[ki + offset], pos);
195  eval_e2iphi(this_block_size, phiV, eikr_r_temp, eikr_i_temp);
196  for (int ki = 0; ki < this_block_size; ki++)
197  {
198  rhok_r_ptr[ki + offset] += eikr_r_temp[ki];
199  rhok_i_ptr[ki + offset] += eikr_i_temp[ki];
200  }
201  }
202 #endif
203  }
204  }
205 }
206 
208 {
209  if (!StorePerParticle)
210  {
211  StorePerParticle = true;
212  computeRhok(P);
213  }
214 }
215 
216 } // namespace qmcplusplus
multi walker shared memory buffer
Definition: StructFact.h:111
a class that defines a supercell in D-dimensional Euclean space.
std::vector< PosType > kpts_cart
K-vector in Cartesian coordinates.
Definition: KContainer.h:53
Matrix< RealType > rhok_r
2-D container for the phase
Definition: StructFact.h:51
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
Matrix< RealType > eikr_i
Definition: StructFact.h:52
const KContainer & k_lists_
K-Vector List.
Definition: StructFact.h:100
size_t getTotalNum() const
Definition: ParticleSet.h:493
Matrix< RealType > rhok_i
Definition: StructFact.h:51
std::ostream & app_log()
Definition: OutputManager.h:65
void resize(size_type n, size_type m)
Resize the container.
Definition: OhmmsMatrix.h:99
T min(T a, T b)
static void mw_updateAllPart(const RefVectorWithLeader< StructFact > &sk_list, const RefVectorWithLeader< ParticleSet > &p_list, SKMultiWalkerMem &mw_mem)
Update RhoK for all particles for multiple walkers particles.
Definition: StructFact.cpp:63
int groups() const
return the number of groups
Definition: ParticleSet.h:511
StructFact(const ParticleLayout &lattice, const KContainer &k_lists)
Constructor - copy ParticleSet and init.
Definition: StructFact.cpp:29
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > lattice
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
void computeRhok(const ParticleSet &P)
Compute all rhok elements from the start.
Definition: StructFact.cpp:138
Introduced to handle virtual moves and ratio computations, e.g.
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
ParticlePos R
Position.
Definition: ParticleSet.h:79
Container for k-points.
Definition: KContainer.h:29
bool StorePerParticle
Whether intermediate data is stored per particle.
Definition: StructFact.h:105
sycl::event copy_n(sycl::queue &aq, const T1 *restrict VA, size_t array_size, T2 *restrict VC, const std::vector< sycl::event > &events)
Definition: syclBLAS.cpp:548
Matrix< RealType, OffloadPinnedAllocator< RealType > > nw_rhok
dist displ for temporary and old pairs
Definition: StructFact.h:116
int SuperCellEnum
enumeration for the methods to handle mixed bconds
Definition: StructFact.h:49
Matrix< RealType > eikr_r
Definition: StructFact.h:52
void sincos(T a, T *restrict s, T *restrict c)
sincos function wrapper
Definition: math.hpp:62
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
Define a LRHandler with two template parameters.
handle math function mapping inside OpenMP offload regions.
void updateAllPart(const ParticleSet &P)
Update Rhok if all particles moved.
Definition: StructFact.cpp:57
NewTimer & update_all_timer_
timer for updateAllPart
Definition: StructFact.h:107
void turnOnStorePerParticle(const ParticleSet &P)
switch on the storage per particle if StorePerParticle was false, this function allocates memory and ...
Definition: StructFact.cpp:207
void eval_e2iphi(int n, const T *restrict phi, T *restrict phase_r, T *restrict phase_i)
Definition: e2iphi.h:61
void resize(int nkpts, int num_species, int num_ptcls)
resize the internal data
Definition: StructFact.cpp:45
int numk
number of k-points
Definition: KContainer.h:40
static bool isQuasi2D()
return true if quasi 2D is selected
int getGroupID(int iat) const
return the group id of a given particle in the particle set.
Definition: ParticleSet.h:520