Loading...
Searching...
No Matches
gpu_kernels_serial.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cmath>
5#include <cstring>
6
7namespace q3 {
8namespace diagonalizer {
9namespace planewave {
10namespace gpu {
11
12void launch_apply_kinetic_energy(int number_of_vectors,
13 int number_of_plane_waves,
14 const double* kinetic_energy,
15 const std::complex<double>* psi,
16 std::complex<double>* hpsi) {
17 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
18 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
19 int offset = vector_index * number_of_plane_waves + g_index;
20 hpsi[offset] = kinetic_energy[g_index] * psi[offset];
21 }
22 }
23}
24
25void launch_apply_kinetic_energy_single(int number_of_vectors,
26 int number_of_plane_waves,
27 const float* kinetic_energy,
28 const std::complex<float>* psi,
29 std::complex<float>* hpsi) {
30 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
31 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
32 int offset = vector_index * number_of_plane_waves + g_index;
33 hpsi[offset] = kinetic_energy[g_index] * psi[offset];
34 }
35 }
36}
37
38void launch_scatter_g_to_fft_grid(int number_of_vectors,
39 int number_of_plane_waves,
40 int local_smooth_grid_points,
41 const int* g_to_fft_mapping,
42 const int* minus_g_to_fft_mapping,
43 bool is_gamma_only,
44 const std::complex<double>* psi,
45 std::complex<double>* fft_workspace) {
46 std::fill_n(fft_workspace,
47 static_cast<std::size_t>(number_of_vectors) * local_smooth_grid_points,
48 std::complex<double>(0.0, 0.0));
49 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
50 const std::complex<double>* psi_vec = &psi[vector_index * number_of_plane_waves];
51 std::complex<double>* workspace_vec =
52 &fft_workspace[vector_index * local_smooth_grid_points];
53 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
54 int fft_index = g_to_fft_mapping[g_index];
55 if (fft_index >= 0) {
56 workspace_vec[fft_index] = psi_vec[g_index];
57 }
58 }
59 if (is_gamma_only && minus_g_to_fft_mapping != nullptr) {
60 for (int g_index = 1; g_index < number_of_plane_waves; ++g_index) {
61 int fft_minus = minus_g_to_fft_mapping[g_index];
62 if (fft_minus >= 0) {
63 workspace_vec[fft_minus] = std::conj(psi_vec[g_index]);
64 }
65 }
66 }
67 }
68}
69
70void launch_scatter_g_to_fft_grid_single(int number_of_vectors,
71 int number_of_plane_waves,
72 int local_smooth_grid_points,
73 const int* g_to_fft_mapping,
74 const int* minus_g_to_fft_mapping,
75 bool is_gamma_only,
76 const std::complex<float>* psi,
77 std::complex<float>* fft_workspace) {
78 std::fill_n(fft_workspace,
79 static_cast<std::size_t>(number_of_vectors) * local_smooth_grid_points,
80 std::complex<float>(0.0F, 0.0F));
81 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
82 const std::complex<float>* psi_vec = &psi[vector_index * number_of_plane_waves];
83 std::complex<float>* workspace_vec =
84 &fft_workspace[vector_index * local_smooth_grid_points];
85 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
86 int fft_index = g_to_fft_mapping[g_index];
87 if (fft_index >= 0) {
88 workspace_vec[fft_index] = psi_vec[g_index];
89 }
90 }
91 if (is_gamma_only && minus_g_to_fft_mapping != nullptr) {
92 for (int g_index = 1; g_index < number_of_plane_waves; ++g_index) {
93 int fft_minus = minus_g_to_fft_mapping[g_index];
94 if (fft_minus >= 0) {
95 workspace_vec[fft_minus] = std::conj(psi_vec[g_index]);
96 }
97 }
98 }
99 }
100}
101
102void launch_scatter_g_to_fft_grid_mixed(int number_of_vectors,
103 int number_of_plane_waves,
104 int local_smooth_grid_points,
105 const int* g_to_fft_mapping,
106 const int* minus_g_to_fft_mapping,
107 bool is_gamma_only,
108 const std::complex<double>* psi,
109 std::complex<float>* fft_workspace) {
110 std::fill_n(fft_workspace,
111 static_cast<std::size_t>(number_of_vectors) * local_smooth_grid_points,
112 std::complex<float>(0.0F, 0.0F));
113 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
114 const std::complex<double>* psi_vec = &psi[vector_index * number_of_plane_waves];
115 std::complex<float>* workspace_vec =
116 &fft_workspace[vector_index * local_smooth_grid_points];
117 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
118 int fft_index = g_to_fft_mapping[g_index];
119 if (fft_index >= 0) {
120 workspace_vec[fft_index] =
121 std::complex<float>(static_cast<float>(psi_vec[g_index].real()),
122 static_cast<float>(psi_vec[g_index].imag()));
123 }
124 }
125 if (is_gamma_only && minus_g_to_fft_mapping != nullptr) {
126 for (int g_index = 1; g_index < number_of_plane_waves; ++g_index) {
127 int fft_minus = minus_g_to_fft_mapping[g_index];
128 if (fft_minus >= 0) {
129 workspace_vec[fft_minus] =
130 std::conj(std::complex<float>(static_cast<float>(psi_vec[g_index].real()),
131 static_cast<float>(psi_vec[g_index].imag())));
132 }
133 }
134 }
135 }
136}
137
138void launch_multiply_potential(int number_of_vectors,
139 int local_smooth_grid_points,
140 const double* potential,
141 std::complex<double>* fft_workspace) {
142 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
143 std::complex<double>* workspace_vec =
144 &fft_workspace[vector_index * local_smooth_grid_points];
145 for (int grid_index = 0; grid_index < local_smooth_grid_points; ++grid_index) {
146 workspace_vec[grid_index] *= potential[grid_index];
147 }
148 }
149}
150
151void launch_multiply_potential_single(int number_of_vectors,
152 int local_smooth_grid_points,
153 const float* potential,
154 std::complex<float>* fft_workspace) {
155 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
156 std::complex<float>* workspace_vec =
157 &fft_workspace[vector_index * local_smooth_grid_points];
158 for (int grid_index = 0; grid_index < local_smooth_grid_points; ++grid_index) {
159 workspace_vec[grid_index] *= potential[grid_index];
160 }
161 }
162}
163
164void launch_gather_fft_grid_to_g(int number_of_vectors,
165 int number_of_plane_waves,
166 int local_smooth_grid_points,
167 const int* g_to_fft_mapping,
168 const std::complex<double>* fft_workspace,
169 std::complex<double>* hpsi) {
170 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
171 std::complex<double>* hpsi_vec = &hpsi[vector_index * number_of_plane_waves];
172 const std::complex<double>* workspace_vec =
173 &fft_workspace[vector_index * local_smooth_grid_points];
174 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
175 int fft_index = g_to_fft_mapping[g_index];
176 if (fft_index >= 0) {
177 hpsi_vec[g_index] += workspace_vec[fft_index];
178 }
179 }
180 }
181}
182
183void launch_gather_fft_grid_to_g_single(int number_of_vectors,
184 int number_of_plane_waves,
185 int local_smooth_grid_points,
186 const int* g_to_fft_mapping,
187 const std::complex<float>* fft_workspace,
188 std::complex<float>* hpsi) {
189 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
190 std::complex<float>* hpsi_vec = &hpsi[vector_index * number_of_plane_waves];
191 const std::complex<float>* workspace_vec =
192 &fft_workspace[vector_index * local_smooth_grid_points];
193 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
194 int fft_index = g_to_fft_mapping[g_index];
195 if (fft_index >= 0) {
196 hpsi_vec[g_index] += workspace_vec[fft_index];
197 }
198 }
199 }
200}
201
202void launch_gather_fft_grid_to_g_mixed(int number_of_vectors,
203 int number_of_plane_waves,
204 int local_smooth_grid_points,
205 const int* g_to_fft_mapping,
206 const std::complex<float>* fft_workspace,
207 std::complex<double>* hpsi) {
208 for (int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
209 std::complex<double>* hpsi_vec = &hpsi[vector_index * number_of_plane_waves];
210 const std::complex<float>* workspace_vec =
211 &fft_workspace[vector_index * local_smooth_grid_points];
212 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
213 int fft_index = g_to_fft_mapping[g_index];
214 if (fft_index >= 0) {
215 hpsi_vec[g_index] +=
216 std::complex<double>(static_cast<double>(workspace_vec[fft_index].real()),
217 static_cast<double>(workspace_vec[fft_index].imag()));
218 }
219 }
220 }
221}
222
223void launch_compute_residuals(int number_of_bands,
224 int number_of_plane_waves,
225 const double* eigenvalues,
226 const std::complex<double>* hamiltonian_ritz_vectors,
227 const std::complex<double>* overlap_ritz_vectors,
228 std::complex<double>* residual_wavefunctions) {
229 for (int band_index = 0; band_index < number_of_bands; ++band_index) {
230 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
231 int offset = band_index * number_of_plane_waves + g_index;
232 residual_wavefunctions[offset] = hamiltonian_ritz_vectors[offset] -
233 eigenvalues[band_index] * overlap_ritz_vectors[offset];
234 }
235 }
236}
237
238void launch_apply_preconditioner(int number_of_bands,
239 int number_of_plane_waves,
240 const double* kinetic_energy_squared,
241 const double* eigenvalues,
242 const bool* band_converged,
243 double floor_value,
244 std::complex<double>* residual_wavefunctions) {
245 for (int band_index = 0; band_index < number_of_bands; ++band_index) {
246 if (band_converged[band_index]) {
247 continue;
248 }
249 std::complex<double>* residual =
250 &residual_wavefunctions[band_index * number_of_plane_waves];
251 for (int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
252 double value_x = kinetic_energy_squared[g_index] - eigenvalues[band_index];
253 double denominator =
254 0.5 * (1.0 + value_x + std::sqrt(1.0 + (value_x - 1.0) * (value_x - 1.0)));
255 if (denominator < floor_value) {
256 denominator = floor_value;
257 }
258 residual[g_index] /= denominator;
259 }
260 }
261}
262
263} // namespace gpu
264} // namespace planewave
265} // namespace diagonalizer
266} // namespace q3
void launch_apply_preconditioner(int number_of_bands, int number_of_plane_waves, const double *kinetic_energy_squared, const double *eigenvalues, const bool *band_converged, double floor_value, std::complex< double > *residual_wavefunctions)
void launch_apply_kinetic_energy_single(int number_of_vectors, int number_of_plane_waves, const float *kinetic_energy, const std::complex< float > *psi, std::complex< float > *hpsi)
void launch_gather_fft_grid_to_g_single(int number_of_vectors, int number_of_plane_waves, int local_smooth_grid_points, const int *g_to_fft_mapping, const std::complex< float > *fft_workspace, std::complex< float > *hpsi)
void launch_apply_kinetic_energy(int number_of_vectors, int number_of_plane_waves, const double *kinetic_energy, const std::complex< double > *psi, std::complex< double > *hpsi)
void launch_multiply_potential(int number_of_vectors, int local_smooth_grid_points, const double *potential, std::complex< double > *fft_workspace)
void launch_multiply_potential_single(int number_of_vectors, int local_smooth_grid_points, const float *potential, std::complex< float > *fft_workspace)
void launch_gather_fft_grid_to_g_mixed(int number_of_vectors, int number_of_plane_waves, int local_smooth_grid_points, const int *g_to_fft_mapping, const std::complex< float > *fft_workspace, std::complex< double > *hpsi)
void launch_scatter_g_to_fft_grid(int number_of_vectors, int number_of_plane_waves, int local_smooth_grid_points, const int *g_to_fft_mapping, const int *minus_g_to_fft_mapping, bool is_gamma_only, const std::complex< double > *psi, std::complex< double > *fft_workspace)
void launch_gather_fft_grid_to_g(int number_of_vectors, int number_of_plane_waves, int local_smooth_grid_points, const int *g_to_fft_mapping, const std::complex< double > *fft_workspace, std::complex< double > *hpsi)
void launch_compute_residuals(int number_of_bands, int number_of_plane_waves, const double *eigenvalues, const std::complex< double > *hamiltonian_ritz_vectors, const std::complex< double > *overlap_ritz_vectors, std::complex< double > *residual_wavefunctions)
void launch_scatter_g_to_fft_grid_mixed(int number_of_vectors, int number_of_plane_waves, int local_smooth_grid_points, const int *g_to_fft_mapping, const int *minus_g_to_fft_mapping, bool is_gamma_only, const std::complex< double > *psi, std::complex< float > *fft_workspace)
void launch_scatter_g_to_fft_grid_single(int number_of_vectors, int number_of_plane_waves, int local_smooth_grid_points, const int *g_to_fft_mapping, const int *minus_g_to_fft_mapping, bool is_gamma_only, const std::complex< float > *psi, std::complex< float > *fft_workspace)