ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
pw_gatherscatter.h
Go to the documentation of this file.
1#include "pw_basis.h"
3#include "source_base/timer.h"
4#include <typeinfo>
5
6namespace ModulePW
7{
15template <typename T>
16void PW_Basis::gatherp_scatters(std::complex<T>* in, std::complex<T>* out) const
17{
18
19 if(this->poolnproc == 1) //In this case nst=nstot, nz = nplane,
20 {
21 const int nst_ = this->nst;
22 const int nz_ = this->nz;
23 const int* istot2ixy_ = this->istot2ixy;
24#ifdef _OPENMP
25#pragma omp parallel for
26#endif
27 for(int is = 0 ; is < nst_ ; ++is)
28 {
29 int ixy = istot2ixy_[is];
30 std::complex<T> *outp = &out[is*nz_];
31 std::complex<T> *inp = &in[ixy*nz_];
32 for(int iz = 0 ; iz < nz_ ; ++iz)
33 {
34 outp[iz] = inp[iz];
35 }
36 }
37 return;
38 }
39
40
41#ifdef __MPI
42 //change (nplane fftnxy) to (nplane,nstot)
43 // Hence, we can send them at one time.
44 const int nstot_gps = this->nstot;
45 const int nplane_gps = this->nplane;
46 const int* istot2ixy_gps = this->istot2ixy;
47#ifdef _OPENMP
48 #pragma omp parallel for
49#endif
50 for (int istot = 0; istot < nstot_gps; ++istot)
51 {
52 int ixy = istot2ixy_gps[istot];
53 std::complex<T> *outp = &out[istot * nplane_gps];
54 std::complex<T> *inp = &in[ixy * nplane_gps];
55 for (int iz = 0; iz < nplane_gps; ++iz)
56 {
57 outp[iz] = inp[iz];
58 }
59 }
60
61 //exchange data
62 //(nplane,nstot) to (numz[ip],ns, poolnproc)
63 if(typeid(T) == typeid(double))
64 {
65 MPI_Alltoallv(out, numr, startr, MPI_DOUBLE_COMPLEX, in, numg, startg, MPI_DOUBLE_COMPLEX, this->pool_world);
66 }
67 else if(typeid(T) == typeid(float))
68 {
69 MPI_Alltoallv(out, numr, startr, MPI_COMPLEX, in, numg, startg, MPI_COMPLEX, this->pool_world);
70 }
71 else
72 {
73 ModuleBase::WARNING_QUIT("PW_Basis::gatherp_scatters", "Unsupported data type for MPI_Alltoallv");
74 }
75
76 // change (nz,ns) to (numz[ip],ns, poolnproc)
77 const int poolnproc_gps = this->poolnproc;
78 const int nst_gps = this->nst;
79 const int nz_gps = this->nz;
80 const int* numz_gps = this->numz;
81 const int* startg_gps = this->startg;
82 const int* startz_gps = this->startz;
83#ifdef _OPENMP
84 #pragma omp parallel for collapse(2)
85#endif
86 for (int ip = 0; ip < poolnproc_gps ;++ip)
87 {
88 for (int is = 0; is < nst_gps; ++is)
89 {
90 int nzip = numz_gps[ip];
91 std::complex<T> *outp0 = &out[startz_gps[ip]];
92 std::complex<T> *inp0 = &in[startg_gps[ip]];
93 std::complex<T> *outp = &outp0[is * nz_gps];
94 std::complex<T> *inp = &inp0[is * nzip ];
95 for (int izip = 0; izip < nzip; ++izip)
96 {
97 outp[izip] = inp[izip];
98 }
99 }
100 }
101#endif
102 return;
103}
104
112template <typename T>
113void PW_Basis::gathers_scatterp(std::complex<T>* in, std::complex<T>* out) const
114{
115 if(this->poolnproc == 1) //In this case nrxx=fftnx*fftny*nz, nst = nstot,
116 {
117 const int nrxx_ = this->nrxx;
118 const int nst_ = this->nst;
119 const int nz_ = this->nz;
120 const int* istot2ixy_ = this->istot2ixy;
121#ifdef _OPENMP
122#pragma omp parallel for schedule(static)
123#endif
124 for(int i = 0; i < nrxx_; ++i)
125 {
126 out[i] = std::complex<T>(0, 0);
127 }
128
129#ifdef _OPENMP
130#pragma omp parallel for
131#endif
132 for(int is = 0 ; is < nst_ ; ++is)
133 {
134 int ixy = istot2ixy_[is];
135 std::complex<T> *outp = &out[ixy*nz_];
136 std::complex<T> *inp = &in[is*nz_];
137 for(int iz = 0 ; iz < nz_ ; ++iz)
138 {
139 outp[iz] = inp[iz];
140 }
141 }
142 return;
143 }
144
145
146#ifdef __MPI
147 // change (nz,ns) to (numz[ip],ns, poolnproc)
148 // Hence, we can send them at one time.
149 const int poolnproc_ = this->poolnproc;
150 const int nst_ = this->nst;
151 const int nz_ = this->nz;
152 const int* numz_ = this->numz;
153 const int* startg_ = this->startg;
154 const int* startz_ = this->startz;
155#ifdef _OPENMP
156 #pragma omp parallel for collapse(2)
157#endif
158 for (int ip = 0; ip < poolnproc_ ;++ip)
159 {
160 for (int is = 0; is < nst_; ++is)
161 {
162 int nzip = numz_[ip];
163 std::complex<T> *outp0 = &out[startg_[ip]];
164 std::complex<T> *inp0 = &in[startz_[ip]];
165 std::complex<T> *outp = &outp0[is * nzip];
166 std::complex<T> *inp = &inp0[is * nz_ ];
167 for (int izip = 0; izip < nzip; ++izip)
168 {
169 outp[izip] = inp[izip];
170 }
171 }
172 }
173
174 //exchange data
175 //(numz[ip],ns, poolnproc) to (nplane,nstot)
176 if(typeid(T) == typeid(double))
177 {
178 MPI_Alltoallv(out, numg, startg, MPI_DOUBLE_COMPLEX, in, numr, startr, MPI_DOUBLE_COMPLEX, this->pool_world);
179 }
180 else if(typeid(T) == typeid(float))
181 {
182 MPI_Alltoallv(out, numg, startg, MPI_COMPLEX, in, numr, startr, MPI_COMPLEX, this->pool_world);
183 }
184 else
185 {
186 ModuleBase::WARNING_QUIT("PW_Basis::gathers_scatterp", "Unsupported data type for MPI_Alltoallv");
187 }
188
189 const int nrxx_gsp = this->nrxx;
190#ifdef _OPENMP
191 #pragma omp parallel for schedule(static)
192#endif
193 for(int i = 0; i < nrxx_gsp; ++i)
194 {
195 out[i] = std::complex<T>(0, 0);
196 }
197 //change (nplane,nstot) to (nplane fftnxy)
198 const int nstot = this->nstot;
199 const int nplane = this->nplane;
200 const int* istot2ixy = this->istot2ixy;
201#ifdef _OPENMP
202#pragma omp parallel for
203#endif
204 for (int istot = 0;istot < nstot; ++istot)
205 {
206 int ixy = istot2ixy[istot];
207 //int ixy = (ixy / fftny)*ny + ixy % fftny;
208 std::complex<T> *outp = &out[ixy * nplane];
209 std::complex<T> *inp = &in[istot * nplane];
210 for (int iz = 0; iz < nplane; ++iz)
211 {
212 outp[iz] = inp[iz];
213 }
214 }
215#endif
216 return;
217}
218
219
220
221}
const std::complex< double > i
Definition cal_pLpR.cpp:46
int nrxx
Definition pw_basis.h:120
int nst
Definition pw_basis.h:111
int nstot
Definition pw_basis.h:114
int * numz
Definition pw_basis.h:122
int poolnproc
Definition pw_basis.h:182
void gatherp_scatters(std::complex< T > *in, std::complex< T > *out) const
gather planes and scatter sticks
Definition pw_gatherscatter.h:16
int * startr
Definition pw_basis.h:126
int * startg
Definition pw_basis.h:125
int * numr
Definition pw_basis.h:124
int * istot2ixy
Definition pw_basis.h:108
int nplane
Definition pw_basis.h:128
MPI_Comm pool_world
Definition pw_basis.h:103
void gathers_scatterp(std::complex< T > *in, std::complex< T > *out) const
gather sticks and scatter planes
Definition pw_gatherscatter.h:113
int * numg
Definition pw_basis.h:123
int * startz
Definition pw_basis.h:121
int nz
Definition pw_basis.h:239
#define T
Definition exp.cpp:237
void WARNING_QUIT(const std::string &, const std::string &)
Combine the functions of WARNING and QUIT.
Definition test_delley.cpp:14
Definition pw_op.cpp:3