42 int number_of_candidates,
43 int number_of_plane_waves,
47 Complex* overlap_basis_vectors)
override {
48 if (number_of_candidates == 0) {
51 int leading_dimension = std::max(number_of_plane_waves, 1);
52 int double_leading_dimension = 2 * leading_dimension;
61 const bool overlap_is_aliased = (overlap_basis_vectors == basis_vectors);
63 if (!overlap_is_aliased) {
65 number_of_plane_waves,
67 &basis_vectors[starting_vector_index * number_of_plane_waves],
68 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
71 int number_of_existing = starting_vector_index;
72 if (number_of_existing > 0) {
74 int double_number_of_plane_waves = 2 * number_of_plane_waves;
75 double alpha_two = 2.0;
76 double d_beta_zero = 0.0;
78 auto* real_basis =
reinterpret_cast<double*
>(
const_cast<Complex*
>(basis_vectors));
79 auto* real_candidates_sv =
reinterpret_cast<double*
>(
80 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
82 std::vector<double> overlap_coefficients(number_of_existing * number_of_candidates,
87 &number_of_candidates,
88 &double_number_of_plane_waves,
91 &double_leading_dimension,
93 &double_leading_dimension,
95 overlap_coefficients.data(),
98 if (gamma_origin_is_local_) {
99 for (
int candidate_index = 0; candidate_index < number_of_candidates;
101 for (
int basis_index = 0; basis_index < number_of_existing; ++basis_index) {
102 Complex basis_g0 = basis_vectors[basis_index * number_of_plane_waves];
104 overlap_basis_vectors[(starting_vector_index + candidate_index) *
105 number_of_plane_waves];
106 overlap_coefficients[candidate_index * number_of_existing +
108 (std::conj(basis_g0) * sv_g0).real();
114 number_of_existing * number_of_candidates);
116 auto* real_candidates =
reinterpret_cast<double*
>(
117 &basis_vectors[starting_vector_index * number_of_plane_waves]);
118 auto* real_overlap_basis =
reinterpret_cast<double*
>(overlap_basis_vectors);
120 double alpha_neg_one = -1.0;
121 double beta_one = 1.0;
124 &double_number_of_plane_waves,
125 &number_of_candidates,
129 &double_leading_dimension,
130 overlap_coefficients.data(),
134 &double_leading_dimension);
136 if (!overlap_is_aliased) {
142 &double_number_of_plane_waves,
143 &number_of_candidates,
147 &double_leading_dimension,
148 overlap_coefficients.data(),
152 &double_leading_dimension);
155 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0);
157 reinterpret_cast<std::complex<double>*
>(
const_cast<Complex*
>(basis_vectors));
158 auto* cast_candidates_sv =
reinterpret_cast<std::complex<double>*
>(
159 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
160 auto* cast_alpha =
reinterpret_cast<std::complex<double>*
>(&alpha_one);
161 auto* cast_beta =
reinterpret_cast<std::complex<double>*
>(&beta_zero);
163 std::vector<Complex> overlap_coefficients(number_of_existing * number_of_candidates,
166 reinterpret_cast<std::complex<double>*
>(overlap_coefficients.data());
170 &number_of_candidates,
171 &number_of_plane_waves,
179 &number_of_existing);
182 number_of_existing * number_of_candidates);
184 auto* cast_candidates =
reinterpret_cast<std::complex<double>*
>(
185 &basis_vectors[starting_vector_index * number_of_plane_waves]);
186 auto* cast_overlap_basis =
187 reinterpret_cast<std::complex<double>*
>(overlap_basis_vectors);
189 Complex alpha_neg_one(-1.0, 0.0), beta_one(1.0, 0.0);
190 auto* cast_alpha_neg =
reinterpret_cast<std::complex<double>*
>(&alpha_neg_one);
191 auto* cast_beta_one =
reinterpret_cast<std::complex<double>*
>(&beta_one);
194 &number_of_plane_waves,
195 &number_of_candidates,
206 if (!overlap_is_aliased) {
212 &number_of_plane_waves,
213 &number_of_candidates,
229 int double_number_of_plane_waves = 2 * number_of_plane_waves;
230 auto* real_candidates =
reinterpret_cast<double*
>(
231 &basis_vectors[starting_vector_index * number_of_plane_waves]);
232 auto* real_candidates_sv =
reinterpret_cast<double*
>(
233 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
235 std::vector<double> cholesky_factor(number_of_candidates * number_of_candidates, 0.0);
236 double alpha_two = 2.0;
237 double beta_zero = 0.0;
240 &number_of_candidates,
241 &number_of_candidates,
242 &double_number_of_plane_waves,
245 &double_leading_dimension,
247 &double_leading_dimension,
249 cholesky_factor.data(),
250 &number_of_candidates);
252 if (gamma_origin_is_local_) {
253 for (
int column_index = 0; column_index < number_of_candidates; ++column_index) {
254 for (
int row_index = 0; row_index < number_of_candidates; ++row_index) {
255 Complex vi_g0 = basis_vectors[(starting_vector_index + row_index) *
256 number_of_plane_waves];
258 overlap_basis_vectors[(starting_vector_index + column_index) *
259 number_of_plane_waves];
260 cholesky_factor[column_index * number_of_candidates + row_index] -=
261 (std::conj(vi_g0) * svj_g0).real();
267 number_of_candidates * number_of_candidates);
271 "U", &number_of_candidates, cholesky_factor.data(), &number_of_candidates, &info);
273 double d_alpha_one = 1.0;
278 &double_number_of_plane_waves,
279 &number_of_candidates,
281 cholesky_factor.data(),
282 &number_of_candidates,
284 &double_leading_dimension);
285 if (!overlap_is_aliased) {
293 &double_number_of_plane_waves,
294 &number_of_candidates,
296 cholesky_factor.data(),
297 &number_of_candidates,
299 &double_leading_dimension);
301 return number_of_candidates;
304 auto* cast_candidates =
reinterpret_cast<std::complex<double>*
>(
305 &basis_vectors[starting_vector_index * number_of_plane_waves]);
306 auto* cast_candidates_sv =
reinterpret_cast<std::complex<double>*
>(
307 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
309 std::vector<Complex> cholesky_factor(number_of_candidates * number_of_candidates,
311 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0);
312 auto* cast_alpha =
reinterpret_cast<std::complex<double>*
>(&alpha_one);
313 auto* cast_beta =
reinterpret_cast<std::complex<double>*
>(&beta_zero);
314 auto* cast_cholesky_factor =
315 reinterpret_cast<std::complex<double>*
>(cholesky_factor.data());
318 &number_of_candidates,
319 &number_of_candidates,
320 &number_of_plane_waves,
327 cast_cholesky_factor,
328 &number_of_candidates);
331 number_of_candidates * number_of_candidates);
335 "U", &number_of_candidates, cast_cholesky_factor, &number_of_candidates, &info);
338 auto* cast_alpha_one =
reinterpret_cast<std::complex<double>*
>(&z_alpha_one);
343 &number_of_plane_waves,
344 &number_of_candidates,
346 cast_cholesky_factor,
347 &number_of_candidates,
350 if (!overlap_is_aliased) {
358 &number_of_plane_waves,
359 &number_of_candidates,
361 cast_cholesky_factor,
362 &number_of_candidates,
366 return number_of_candidates;
371 int accepted_count = 0;
372 int one_increment = 1;
373 std::vector<double> batch_coefficients_buffer(number_of_candidates, 0.0);
374 std::vector<Complex> z_batch_coefficients_buffer(number_of_candidates,
Complex(0.0, 0.0));
376 for (
int candidate_index = 0; candidate_index < number_of_candidates; ++candidate_index) {
377 int source_index = starting_vector_index + candidate_index;
378 int destination_index = starting_vector_index + accepted_count;
380 if (destination_index != source_index) {
381 std::memcpy(&basis_vectors[destination_index * number_of_plane_waves],
382 &basis_vectors[source_index * number_of_plane_waves],
383 number_of_plane_waves *
sizeof(
Complex));
384 if (!overlap_is_aliased) {
388 std::memcpy(&overlap_basis_vectors[destination_index * number_of_plane_waves],
389 &overlap_basis_vectors[source_index * number_of_plane_waves],
390 number_of_plane_waves *
sizeof(
Complex));
394 auto* current_vector =
reinterpret_cast<std::complex<double>*
>(
395 &basis_vectors[destination_index * number_of_plane_waves]);
396 auto* current_overlap =
reinterpret_cast<std::complex<double>*
>(
397 &overlap_basis_vectors[destination_index * number_of_plane_waves]);
399 int number_of_batch_existing = destination_index - starting_vector_index;
400 if (number_of_batch_existing > 0) {
402 int double_number_of_plane_waves = 2 * number_of_plane_waves;
403 double alpha_two = 2.0;
404 double d_beta_zero = 0.0;
407 auto* real_batch_basis =
reinterpret_cast<double*
>(
408 &basis_vectors[starting_vector_index * number_of_plane_waves]);
409 auto* real_sv =
reinterpret_cast<double*
>(current_overlap);
413 &number_of_batch_existing,
415 &double_number_of_plane_waves,
418 &double_leading_dimension,
420 &double_leading_dimension,
422 batch_coefficients_buffer.data(),
423 &number_of_batch_existing);
425 if (gamma_origin_is_local_) {
426 for (
int basis_index = 0; basis_index < number_of_batch_existing;
428 Complex basis_g0 = basis_vectors[(starting_vector_index + basis_index) *
429 number_of_plane_waves];
431 overlap_basis_vectors[destination_index * number_of_plane_waves];
432 batch_coefficients_buffer[basis_index] -=
433 (std::conj(basis_g0) * sv_g0).real();
438 number_of_batch_existing);
440 double alpha_neg_one = -1.0;
441 double beta_one = 1.0;
443 &double_number_of_plane_waves,
444 &number_of_batch_existing,
447 &double_leading_dimension,
448 batch_coefficients_buffer.data(),
451 reinterpret_cast<double*
>(current_vector),
454 auto* real_batch_overlap =
reinterpret_cast<double*
>(
455 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
456 if (!overlap_is_aliased) {
461 &double_number_of_plane_waves,
462 &number_of_batch_existing,
465 &double_leading_dimension,
466 batch_coefficients_buffer.data(),
469 reinterpret_cast<double*
>(current_overlap),
474 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0);
475 auto* cast_batch_basis =
reinterpret_cast<std::complex<double>*
>(
476 &basis_vectors[starting_vector_index * number_of_plane_waves]);
477 auto* cast_alpha =
reinterpret_cast<std::complex<double>*
>(&alpha_one);
478 auto* cast_beta =
reinterpret_cast<std::complex<double>*
>(&beta_zero);
480 reinterpret_cast<std::complex<double>*
>(z_batch_coefficients_buffer.data());
484 &number_of_batch_existing,
486 &number_of_plane_waves,
494 &number_of_batch_existing);
497 number_of_batch_existing);
499 Complex alpha_neg_one(-1.0, 0.0), beta_one(1.0, 0.0);
500 auto* cast_alpha_neg =
reinterpret_cast<std::complex<double>*
>(&alpha_neg_one);
501 auto* cast_beta_one =
reinterpret_cast<std::complex<double>*
>(&beta_one);
503 &number_of_plane_waves,
504 &number_of_batch_existing,
514 auto* cast_batch_overlap =
reinterpret_cast<std::complex<double>*
>(
515 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
516 if (!overlap_is_aliased) {
521 &number_of_plane_waves,
522 &number_of_batch_existing,
535 Real norm_squared = gamma_aware_real_dot(
536 is_gamma_only, number_of_plane_waves, current_vector, current_overlap);
539 double inverse_norm = 1.0 / std::sqrt(norm_squared);
541 &number_of_plane_waves, &inverse_norm, current_vector, &one_increment);
542 if (!overlap_is_aliased) {
547 &number_of_plane_waves, &inverse_norm, current_overlap, &one_increment);
552 return accepted_count;
557 int total_basis_size,
558 int maximum_basis_size,
559 int number_of_plane_waves,
562 const Complex* hamiltonian_basis_vectors,
563 const Complex* overlap_basis_vectors,
565 Complex* subspace_overlap)
override {
566 int leading_dimension = std::max(number_of_plane_waves, 1);
567 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0);
569 reinterpret_cast<std::complex<double>*
>(
const_cast<Complex*
>(basis_vectors));
570 auto* cast_h_new =
reinterpret_cast<std::complex<double>*
>(
571 const_cast<Complex*
>(&hamiltonian_basis_vectors[start_column * number_of_plane_waves]));
572 auto* cast_s_new =
reinterpret_cast<std::complex<double>*
>(
573 const_cast<Complex*
>(&overlap_basis_vectors[start_column * number_of_plane_waves]));
576 int double_number_of_plane_waves = 2 * number_of_plane_waves;
577 int double_leading_dimension = 2 * leading_dimension;
578 double alpha_two = 2.0;
579 double d_beta_zero = 0.0;
581 auto* real_basis =
reinterpret_cast<double*
>(
const_cast<Complex*
>(basis_vectors));
582 auto* real_h_new =
reinterpret_cast<double*
>(
const_cast<Complex*
>(
583 &hamiltonian_basis_vectors[start_column * number_of_plane_waves]));
584 auto* real_s_new =
reinterpret_cast<double*
>(
585 const_cast<Complex*
>(&overlap_basis_vectors[start_column * number_of_plane_waves]));
587 std::vector<double> h_block_real(
static_cast<size_t>(total_basis_size) * new_columns,
593 &double_number_of_plane_waves,
596 &double_leading_dimension,
598 &double_leading_dimension,
603 std::vector<double> s_block_real(
static_cast<size_t>(total_basis_size) * new_columns,
609 &double_number_of_plane_waves,
612 &double_leading_dimension,
614 &double_leading_dimension,
619 for (
int col = 0; col < new_columns; ++col) {
620 int source_col = start_column + col;
621 Complex h_right_g0 = hamiltonian_basis_vectors[source_col * number_of_plane_waves];
622 Complex s_right_g0 = overlap_basis_vectors[source_col * number_of_plane_waves];
623 for (
int row = 0; row < total_basis_size; ++row) {
624 Complex left_g0 = basis_vectors[row * number_of_plane_waves];
625 int real_index = col * total_basis_size + row;
626 if (gamma_origin_is_local_) {
627 h_block_real[real_index] -= (std::conj(left_g0) * h_right_g0).real();
628 s_block_real[real_index] -= (std::conj(left_g0) * s_right_g0).real();
631 int sub_index = (start_column + col) * maximum_basis_size + row;
632 subspace_hamiltonian[sub_index] =
Complex(h_block_real[real_index], 0.0);
633 subspace_overlap[sub_index] =
Complex(s_block_real[real_index], 0.0);
637 auto* cast_alpha =
reinterpret_cast<std::complex<double>*
>(&alpha_one);
638 auto* cast_beta =
reinterpret_cast<std::complex<double>*
>(&beta_zero);
640 auto* cast_h_block =
reinterpret_cast<std::complex<double>*
>(
641 &subspace_hamiltonian[start_column * maximum_basis_size]);
646 &number_of_plane_waves,
654 &maximum_basis_size);
656 auto* cast_s_block =
reinterpret_cast<std::complex<double>*
>(
657 &subspace_overlap[start_column * maximum_basis_size]);
662 &number_of_plane_waves,
670 &maximum_basis_size);
673 int new_block_size = maximum_basis_size * new_columns;
674 int new_block_offset = start_column * maximum_basis_size;
677 execution_policy_.
reduce_within_group(&subspace_overlap[new_block_offset], new_block_size);
826 int number_of_plane_waves,
828 int maximum_basis_size,
830 bool is_identity_overlap,
832 const Complex* subspace_hamiltonian,
833 const Complex* subspace_overlap,
835 Complex* hamiltonian_basis_vectors,
836 Complex* overlap_basis_vectors,
837 Complex* rotation_scratch)
override {
838 std::vector<Real> eigenvalues_expanded(maximum_basis_size, 0.0);
839 std::vector<Complex> eigenvector_matrix(
static_cast<std::size_t
>(basis_size) * basis_size);
847 if (subspace_hamiltonian !=
nullptr && subspace_overlap !=
nullptr) {
851 subspace_hamiltonian,
853 eigenvalues_expanded.data(),
854 eigenvector_matrix.data());
857 build_subspace_matrices_and_diagonalize(basis_size,
858 number_of_plane_waves,
862 hamiltonian_basis_vectors,
863 overlap_basis_vectors,
864 eigenvalues_expanded,
874 static_cast<int>(eigenvector_matrix.size()));
883 std::size_t collapsed_size =
static_cast<std::size_t
>(number_of_bands) *
884 static_cast<std::size_t
>(number_of_plane_waves);
886 auto* cast_basis =
reinterpret_cast<std::complex<double>*
>(basis_vectors);
887 auto* cast_h_basis =
reinterpret_cast<std::complex<double>*
>(hamiltonian_basis_vectors);
888 auto* cast_s_basis =
reinterpret_cast<std::complex<double>*
>(overlap_basis_vectors);
889 auto* cast_eigvec =
reinterpret_cast<std::complex<double>*
>(eigenvector_matrix.data());
890 auto* cast_scratch =
reinterpret_cast<std::complex<double>*
>(rotation_scratch);
905 std::memcpy(basis_vectors, rotation_scratch, collapsed_size *
sizeof(
Complex));
913 std::memcpy(hamiltonian_basis_vectors, rotation_scratch, collapsed_size *
sizeof(
Complex));
927 const bool overlap_needs_rotation =
928 !is_identity_overlap || overlap_basis_vectors != basis_vectors;
929 if (overlap_needs_rotation) {
936 std::memcpy(overlap_basis_vectors, rotation_scratch, collapsed_size *
sizeof(
Complex));
939 enforce_gamma_g0_real(is_gamma_only, number_of_plane_waves, number_of_bands, basis_vectors);
940 enforce_gamma_g0_real(
941 is_gamma_only, number_of_plane_waves, number_of_bands, hamiltonian_basis_vectors);
942 enforce_gamma_g0_real(
943 is_gamma_only, number_of_plane_waves, number_of_bands, overlap_basis_vectors);
944 return number_of_bands;
996 int number_of_plane_waves,
998 int maximum_candidates,
1000 const Complex* eigenvector_matrix,
1001 int eigenvector_leading_dimension,
1002 const Real* eigenvalues,
1003 const std::vector<bool>& band_converged,
1004 const Real* kinetic_energy_squared,
1005 const Complex* hamiltonian_basis_vectors,
1006 const Complex* overlap_basis_vectors,
1007 Complex* correction_columns)
override {
1013 std::vector<int> source_bands;
1014 source_bands.reserve(
static_cast<std::size_t
>(number_of_bands));
1015 for (
int band_index = 0; band_index < number_of_bands; ++band_index) {
1016 if (!band_converged[band_index] &&
1017 static_cast<int>(source_bands.size()) < maximum_candidates) {
1018 source_bands.push_back(band_index);
1021 int number_of_candidates =
static_cast<int>(source_bands.size());
1022 if (number_of_candidates == 0) {
1026 std::vector<Complex> packed_coefficients(
static_cast<std::size_t
>(basis_size) *
1027 static_cast<std::size_t
>(number_of_candidates),
1029 std::vector<Real> candidate_eigenvalues(
static_cast<std::size_t
>(number_of_candidates),
1031 for (
int candidate_index = 0; candidate_index < number_of_candidates; ++candidate_index) {
1032 int band_index = source_bands[
static_cast<std::size_t
>(candidate_index)];
1033 candidate_eigenvalues[
static_cast<std::size_t
>(candidate_index)] =
1034 eigenvalues[band_index];
1036 &packed_coefficients[
static_cast<std::size_t
>(candidate_index) * basis_size],
1037 eigenvector_matrix +
static_cast<std::size_t
>(band_index) *
1038 static_cast<std::size_t
>(eigenvector_leading_dimension),
1039 static_cast<std::size_t
>(basis_size) *
sizeof(
Complex));
1049 bool distribute = band_group_size > 1 && number_of_candidates >= band_group_size;
1050 int first_column = 0;
1051 int local_columns = number_of_candidates;
1057 number_of_plane_waves);
1062 if (local_columns > 0) {
1063 int leading_dimension = std::max(number_of_plane_waves, 1);
1064 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0), beta_one(1.0, 0.0);
1065 auto* cast_alpha =
reinterpret_cast<std::complex<double>*
>(&alpha_one);
1066 auto* cast_beta_zero =
reinterpret_cast<std::complex<double>*
>(&beta_zero);
1067 auto* cast_beta_one =
reinterpret_cast<std::complex<double>*
>(&beta_one);
1068 auto* cast_coefficients =
reinterpret_cast<std::complex<double>*
>(
1069 packed_coefficients.data() +
static_cast<std::size_t
>(first_column) * basis_size);
1070 auto* cast_destination =
reinterpret_cast<std::complex<double>*
>(
1071 correction_columns +
1072 static_cast<std::size_t
>(first_column) * number_of_plane_waves);
1076 &number_of_plane_waves,
1080 reinterpret_cast<std::complex<double>*
>(
1081 const_cast<Complex*
>(overlap_basis_vectors)),
1087 &leading_dimension);
1089 for (
int local_index = 0; local_index < local_columns; ++local_index) {
1090 Real negative_eigenvalue =
1091 -candidate_eigenvalues[
static_cast<std::size_t
>(first_column + local_index)];
1093 correction_columns +
1094 static_cast<std::size_t
>(first_column + local_index) * number_of_plane_waves;
1095 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
1096 column[g_index] *= negative_eigenvalue;
1102 &number_of_plane_waves,
1106 reinterpret_cast<std::complex<double>*
>(
1107 const_cast<Complex*
>(hamiltonian_basis_vectors)),
1113 &leading_dimension);
1116 number_of_plane_waves,
1117 kinetic_energy_squared,
1118 candidate_eigenvalues.data() + first_column,
1119 correction_columns +
1120 static_cast<std::size_t
>(first_column) *
1121 number_of_plane_waves);
1129 enforce_gamma_g0_real(
1130 is_gamma_only, number_of_plane_waves, number_of_candidates, correction_columns);
1131 return number_of_candidates;