68 int number_of_candidates,
69 int number_of_plane_waves,
73 Complex* overlap_basis_vectors)
override {
74 if (number_of_candidates == 0) {
78 int leading_dimension = std::max(number_of_plane_waves, 1);
82 number_of_plane_waves,
84 &basis_vectors[starting_vector_index * number_of_plane_waves],
85 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
87 int number_of_existing = starting_vector_index;
90 if (number_of_existing > 0 && !is_gamma_only) {
91 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0);
94 std::vector<Complex> overlap_coefficients(number_of_existing * number_of_candidates,
97 number_of_existing * number_of_candidates, device_backend_);
102 number_of_candidates,
103 number_of_plane_waves,
107 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves],
110 device_overlap_coefficients.
data(),
113 device_backend_->synchronize();
115 std::memcpy(overlap_coefficients.data(),
116 device_overlap_coefficients.
data(),
117 overlap_coefficients.size() *
sizeof(
Complex));
120 number_of_existing * number_of_candidates);
122 std::memcpy(device_overlap_coefficients.
data(),
123 overlap_coefficients.data(),
124 overlap_coefficients.size() *
sizeof(
Complex));
127 Complex alpha_neg_one(-1.0, 0.0), beta_one(1.0, 0.0);
130 number_of_plane_waves,
131 number_of_candidates,
136 device_overlap_coefficients.
data(),
139 &basis_vectors[starting_vector_index * number_of_plane_waves],
145 number_of_plane_waves,
146 number_of_candidates,
149 overlap_basis_vectors,
151 device_overlap_coefficients.
data(),
154 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves],
157 device_backend_->synchronize();
158 }
else if (number_of_existing > 0 && is_gamma_only) {
160 int double_number_of_plane_waves = 2 * number_of_plane_waves;
161 int double_leading_dimension = 2 * leading_dimension;
162 double alpha_two = 2.0;
163 double d_beta_zero = 0.0;
165 auto* real_basis =
reinterpret_cast<double*
>(
const_cast<Complex*
>(basis_vectors));
166 auto* real_candidates_sv =
reinterpret_cast<double*
>(
167 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
169 std::vector<double> overlap_coefficients(number_of_existing * number_of_candidates,
172 number_of_existing * number_of_candidates, device_backend_);
178 number_of_candidates,
179 double_number_of_plane_waves,
182 double_leading_dimension,
184 double_leading_dimension,
186 device_overlap_coefficients.
data(),
189 device_backend_->synchronize();
191 std::memcpy(overlap_coefficients.data(),
192 device_overlap_coefficients.
data(),
193 overlap_coefficients.size() *
sizeof(
double));
196 if (gamma_origin_is_local_) {
197 for (
int candidate_index = 0; candidate_index < number_of_candidates;
199 for (
int basis_index = 0; basis_index < number_of_existing; ++basis_index) {
200 Complex basis_g0 = basis_vectors[basis_index * number_of_plane_waves];
202 overlap_basis_vectors[(starting_vector_index + candidate_index) *
203 number_of_plane_waves];
204 overlap_coefficients[candidate_index * number_of_existing + basis_index] -=
205 (std::conj(basis_g0) * sv_g0).real();
211 number_of_existing * number_of_candidates);
213 std::memcpy(device_overlap_coefficients.
data(),
214 overlap_coefficients.data(),
215 overlap_coefficients.size() *
sizeof(
double));
217 auto* real_candidates =
reinterpret_cast<double*
>(
218 &basis_vectors[starting_vector_index * number_of_plane_waves]);
219 auto* real_overlap_basis =
reinterpret_cast<double*
>(overlap_basis_vectors);
221 double alpha_neg_one = -1.0;
222 double beta_one = 1.0;
227 double_number_of_plane_waves,
228 number_of_candidates,
232 double_leading_dimension,
233 device_overlap_coefficients.
data(),
237 double_leading_dimension);
242 double_number_of_plane_waves,
243 number_of_candidates,
247 double_leading_dimension,
248 device_overlap_coefficients.
data(),
252 double_leading_dimension);
254 device_backend_->synchronize();
258 if (!is_gamma_only) {
259 auto* cast_candidates =
reinterpret_cast<std::complex<double>*
>(
260 &basis_vectors[starting_vector_index * number_of_plane_waves]);
261 auto* cast_candidates_sv =
reinterpret_cast<std::complex<double>*
>(
262 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
264 std::vector<Complex> cholesky_factor(number_of_candidates * number_of_candidates,
267 number_of_candidates * number_of_candidates, device_backend_);
268 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0);
272 number_of_candidates,
273 number_of_candidates,
274 number_of_plane_waves,
276 &basis_vectors[starting_vector_index * number_of_plane_waves],
278 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves],
281 device_cholesky_factor.
data(),
282 number_of_candidates);
284 device_backend_->synchronize();
286 std::memcpy(cholesky_factor.data(),
287 device_cholesky_factor.
data(),
288 cholesky_factor.size() *
sizeof(
Complex));
291 number_of_candidates * number_of_candidates);
294 auto* cast_cholesky_factor =
295 reinterpret_cast<std::complex<double>*
>(cholesky_factor.data());
297 "U", &number_of_candidates, cast_cholesky_factor, &number_of_candidates, &info);
300 auto* cast_alpha_one =
reinterpret_cast<std::complex<double>*
>(&z_alpha_one);
305 &number_of_plane_waves,
306 &number_of_candidates,
308 cast_cholesky_factor,
309 &number_of_candidates,
316 &number_of_plane_waves,
317 &number_of_candidates,
319 cast_cholesky_factor,
320 &number_of_candidates,
323 return number_of_candidates;
327 int double_number_of_plane_waves = 2 * number_of_plane_waves;
328 int double_leading_dimension = 2 * leading_dimension;
329 auto* real_candidates =
reinterpret_cast<double*
>(
330 &basis_vectors[starting_vector_index * number_of_plane_waves]);
331 auto* real_candidates_sv =
reinterpret_cast<double*
>(
332 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
334 std::vector<double> cholesky_factor(number_of_candidates * number_of_candidates, 0.0);
336 number_of_candidates * number_of_candidates, device_backend_);
337 double alpha_two = 2.0;
338 double beta_zero = 0.0;
341 number_of_candidates,
342 number_of_candidates,
343 double_number_of_plane_waves,
346 double_leading_dimension,
348 double_leading_dimension,
350 device_cholesky_factor.
data(),
351 number_of_candidates);
353 device_backend_->synchronize();
355 std::memcpy(cholesky_factor.data(),
356 device_cholesky_factor.
data(),
357 cholesky_factor.size() *
sizeof(
double));
359 if (gamma_origin_is_local_) {
360 for (
int column_index = 0; column_index < number_of_candidates; ++column_index) {
361 for (
int row_index = 0; row_index < number_of_candidates; ++row_index) {
362 Complex vi_g0 = basis_vectors[(starting_vector_index + row_index) *
363 number_of_plane_waves];
365 overlap_basis_vectors[(starting_vector_index + column_index) *
366 number_of_plane_waves];
367 cholesky_factor[column_index * number_of_candidates + row_index] -=
368 (std::conj(vi_g0) * svj_g0).real();
374 number_of_candidates * number_of_candidates);
378 "U", &number_of_candidates, cholesky_factor.data(), &number_of_candidates, &info);
380 double d_alpha_one = 1.0;
385 &double_number_of_plane_waves,
386 &number_of_candidates,
388 cholesky_factor.data(),
389 &number_of_candidates,
391 &double_leading_dimension);
396 &double_number_of_plane_waves,
397 &number_of_candidates,
399 cholesky_factor.data(),
400 &number_of_candidates,
402 &double_leading_dimension);
403 return number_of_candidates;
408 int accepted_count = 0;
409 int one_increment = 1;
410 int double_leading_dimension = 2 * leading_dimension;
411 std::vector<double> batch_coefficients_buffer(number_of_candidates, 0.0);
412 std::vector<Complex> z_batch_coefficients_buffer(number_of_candidates,
Complex(0.0, 0.0));
414 for (
int candidate_index = 0; candidate_index < number_of_candidates; ++candidate_index) {
415 int source_index = starting_vector_index + candidate_index;
416 int destination_index = starting_vector_index + accepted_count;
418 if (destination_index != source_index) {
419 std::memcpy(&basis_vectors[destination_index * number_of_plane_waves],
420 &basis_vectors[source_index * number_of_plane_waves],
421 number_of_plane_waves *
sizeof(
Complex));
422 std::memcpy(&overlap_basis_vectors[destination_index * number_of_plane_waves],
423 &overlap_basis_vectors[source_index * number_of_plane_waves],
424 number_of_plane_waves *
sizeof(
Complex));
427 auto* current_vector =
reinterpret_cast<std::complex<double>*
>(
428 &basis_vectors[destination_index * number_of_plane_waves]);
429 auto* current_overlap =
reinterpret_cast<std::complex<double>*
>(
430 &overlap_basis_vectors[destination_index * number_of_plane_waves]);
432 int number_of_batch_existing = destination_index - starting_vector_index;
433 if (number_of_batch_existing > 0) {
435 int double_number_of_plane_waves = 2 * number_of_plane_waves;
436 double alpha_two = 2.0;
437 double d_beta_zero = 0.0;
440 auto* real_batch_basis =
reinterpret_cast<double*
>(
441 &basis_vectors[starting_vector_index * number_of_plane_waves]);
442 auto* real_sv =
reinterpret_cast<double*
>(current_overlap);
446 &number_of_batch_existing,
448 &double_number_of_plane_waves,
451 &double_leading_dimension,
453 &double_leading_dimension,
455 batch_coefficients_buffer.data(),
456 &number_of_batch_existing);
458 if (gamma_origin_is_local_) {
459 for (
int basis_index = 0; basis_index < number_of_batch_existing;
461 Complex basis_g0 = basis_vectors[(starting_vector_index + basis_index) *
462 number_of_plane_waves];
464 overlap_basis_vectors[destination_index * number_of_plane_waves];
465 batch_coefficients_buffer[basis_index] -=
466 (std::conj(basis_g0) * sv_g0).real();
471 number_of_batch_existing);
473 double alpha_neg_one = -1.0;
474 double beta_one = 1.0;
476 &double_number_of_plane_waves,
477 &number_of_batch_existing,
480 &double_leading_dimension,
481 batch_coefficients_buffer.data(),
484 reinterpret_cast<double*
>(current_vector),
487 auto* real_batch_overlap =
reinterpret_cast<double*
>(
488 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
490 &double_number_of_plane_waves,
491 &number_of_batch_existing,
494 &double_leading_dimension,
495 batch_coefficients_buffer.data(),
498 reinterpret_cast<double*
>(current_overlap),
502 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0);
503 auto* cast_batch_basis =
reinterpret_cast<std::complex<double>*
>(
504 &basis_vectors[starting_vector_index * number_of_plane_waves]);
505 auto* cast_alpha =
reinterpret_cast<std::complex<double>*
>(&alpha_one);
506 auto* cast_beta =
reinterpret_cast<std::complex<double>*
>(&beta_zero);
508 reinterpret_cast<std::complex<double>*
>(z_batch_coefficients_buffer.data());
512 &number_of_batch_existing,
514 &number_of_plane_waves,
522 &number_of_batch_existing);
525 number_of_batch_existing);
527 Complex alpha_neg_one(-1.0, 0.0), beta_one(1.0, 0.0);
528 auto* cast_alpha_neg =
reinterpret_cast<std::complex<double>*
>(&alpha_neg_one);
529 auto* cast_beta_one =
reinterpret_cast<std::complex<double>*
>(&beta_one);
531 &number_of_plane_waves,
532 &number_of_batch_existing,
542 auto* cast_batch_overlap =
reinterpret_cast<std::complex<double>*
>(
543 &overlap_basis_vectors[starting_vector_index * number_of_plane_waves]);
545 &number_of_plane_waves,
546 &number_of_batch_existing,
558 Real norm_squared = gamma_aware_real_dot(
559 is_gamma_only, number_of_plane_waves, current_vector, current_overlap);
562 double inverse_norm = 1.0 / std::sqrt(norm_squared);
564 &number_of_plane_waves, &inverse_norm, current_vector, &one_increment);
566 &number_of_plane_waves, &inverse_norm, current_overlap, &one_increment);
570 return accepted_count;
578 int total_basis_size,
579 int maximum_basis_size,
580 int number_of_plane_waves,
583 const Complex* hamiltonian_basis_vectors,
584 const Complex* overlap_basis_vectors,
586 Complex* subspace_overlap)
override {
587 int leading_dimension = std::max(number_of_plane_waves, 1);
591 int double_number_of_plane_waves = 2 * number_of_plane_waves;
592 int double_leading_dimension = 2 * leading_dimension;
593 double alpha_two = 2.0;
594 double d_beta_zero = 0.0;
596 auto* real_basis =
reinterpret_cast<const double*
>(basis_vectors);
597 auto* real_h_new =
reinterpret_cast<const double*
>(
598 &hamiltonian_basis_vectors[start_column * number_of_plane_waves]);
599 auto* real_s_new =
reinterpret_cast<const double*
>(
600 &overlap_basis_vectors[start_column * number_of_plane_waves]);
602 std::vector<double> h_block_real(
static_cast<size_t>(total_basis_size) * new_columns,
604 std::vector<double> s_block_real(
static_cast<size_t>(total_basis_size) * new_columns,
608 total_basis_size * new_columns, device_backend_);
610 total_basis_size * new_columns, device_backend_);
616 double_number_of_plane_waves,
619 double_leading_dimension,
621 double_leading_dimension,
623 device_h_block_real.
data(),
630 double_number_of_plane_waves,
633 double_leading_dimension,
635 double_leading_dimension,
637 device_s_block_real.
data(),
640 device_backend_->synchronize();
642 std::memcpy(h_block_real.data(),
643 device_h_block_real.
data(),
644 h_block_real.size() *
sizeof(
double));
645 std::memcpy(s_block_real.data(),
646 device_s_block_real.
data(),
647 s_block_real.size() *
sizeof(
double));
649 for (
int col = 0; col < new_columns; ++col) {
650 int source_col = start_column + col;
651 Complex h_right_g0 = hamiltonian_basis_vectors[source_col * number_of_plane_waves];
652 Complex s_right_g0 = overlap_basis_vectors[source_col * number_of_plane_waves];
653 for (
int row = 0; row < total_basis_size; ++row) {
654 Complex left_g0 = basis_vectors[row * number_of_plane_waves];
655 int real_index = col * total_basis_size + row;
656 if (gamma_origin_is_local_) {
657 h_block_real[real_index] -= (std::conj(left_g0) * h_right_g0).real();
658 s_block_real[real_index] -= (std::conj(left_g0) * s_right_g0).real();
661 int sub_index = (start_column + col) * maximum_basis_size + row;
662 subspace_hamiltonian[sub_index] =
Complex(h_block_real[real_index], 0.0);
663 subspace_overlap[sub_index] =
Complex(s_block_real[real_index], 0.0);
668 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0);
674 number_of_plane_waves,
678 &hamiltonian_basis_vectors[start_column * number_of_plane_waves],
681 &subspace_hamiltonian[start_column * maximum_basis_size],
688 number_of_plane_waves,
692 &overlap_basis_vectors[start_column * number_of_plane_waves],
695 &subspace_overlap[start_column * maximum_basis_size],
698 device_backend_->synchronize();
701 int new_block_size = maximum_basis_size * new_columns;
702 int new_block_offset = start_column * maximum_basis_size;
705 execution_policy_.
reduce_within_group(&subspace_overlap[new_block_offset], new_block_size);
794 int number_of_plane_waves,
796 int maximum_candidates,
798 const Complex* eigenvector_matrix,
799 int eigenvector_leading_dimension,
800 const Real* eigenvalues,
801 const std::vector<bool>& band_converged,
802 const Real* kinetic_energy_squared,
803 const Complex* hamiltonian_basis_vectors,
804 const Complex* overlap_basis_vectors,
805 Complex* correction_columns)
override {
812 std::vector<int> source_bands;
813 source_bands.reserve(
static_cast<std::size_t
>(number_of_bands));
814 for (
int band_index = 0; band_index < number_of_bands; ++band_index) {
815 if (!band_converged[band_index] &&
816 static_cast<int>(source_bands.size()) < maximum_candidates) {
817 source_bands.push_back(band_index);
820 int number_of_candidates =
static_cast<int>(source_bands.size());
821 if (number_of_candidates == 0) {
826 static_cast<std::size_t
>(basis_size) *
static_cast<std::size_t
>(number_of_candidates),
828 std::vector<Real> candidate_eigenvalues(
static_cast<std::size_t
>(number_of_candidates),
830 for (
int candidate_index = 0; candidate_index < number_of_candidates; ++candidate_index) {
831 int band_index = source_bands[
static_cast<std::size_t
>(candidate_index)];
832 candidate_eigenvalues[
static_cast<std::size_t
>(candidate_index)] =
833 eigenvalues[band_index];
835 device_coefficients.
data() +
static_cast<std::size_t
>(candidate_index) * basis_size,
836 eigenvector_matrix +
static_cast<std::size_t
>(band_index) *
837 static_cast<std::size_t
>(eigenvector_leading_dimension),
838 static_cast<std::size_t
>(basis_size) *
sizeof(
Complex));
841 int leading_dimension = std::max(number_of_plane_waves, 1);
842 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0), beta_one(1.0, 0.0);
846 number_of_plane_waves,
847 number_of_candidates,
850 overlap_basis_vectors,
852 device_coefficients.
data(),
857 device_backend_->synchronize();
859 for (
int candidate_index = 0; candidate_index < number_of_candidates; ++candidate_index) {
861 -candidate_eigenvalues[
static_cast<std::size_t
>(candidate_index)], 0.0);
862 gpu_blas_.
scale(number_of_plane_waves,
865 static_cast<std::size_t
>(candidate_index) * number_of_plane_waves);
867 device_backend_->synchronize();
871 number_of_plane_waves,
872 number_of_candidates,
875 hamiltonian_basis_vectors,
877 device_coefficients.
data(),
882 device_backend_->synchronize();
889 static_cast<std::size_t
>(number_of_candidates), device_backend_);
890 std::memcpy(device_candidate_eigenvalues.
data(),
891 candidate_eigenvalues.data(),
892 static_cast<std::size_t
>(number_of_candidates) *
sizeof(
Real));
893 std::vector<bool> none_converged(
static_cast<std::size_t
>(number_of_candidates),
false);
895 number_of_plane_waves,
896 kinetic_energy_squared,
897 device_candidate_eigenvalues.
data(),
901 enforce_gamma_g0_real(
902 is_gamma_only, number_of_plane_waves, number_of_candidates, correction_columns);
903 return number_of_candidates;
907 int number_of_plane_waves,
909 int maximum_basis_size,
911 bool is_identity_overlap,
913 const Complex* subspace_hamiltonian,
914 const Complex* subspace_overlap,
916 Complex* hamiltonian_basis_vectors,
917 Complex* overlap_basis_vectors,
918 Complex* rotation_scratch)
override {
919 std::vector<Real> eigenvalues_expanded(maximum_basis_size, 0.0);
920 std::vector<Complex> eigenvector_matrix(maximum_basis_size * maximum_basis_size);
927 if (subspace_hamiltonian !=
nullptr && subspace_overlap !=
nullptr) {
931 subspace_hamiltonian,
933 eigenvalues_expanded.data(),
934 eigenvector_matrix.data());
937 build_subspace_matrices_and_diagonalize(basis_size,
938 number_of_plane_waves,
942 hamiltonian_basis_vectors,
943 overlap_basis_vectors,
944 eigenvalues_expanded.data(),
945 eigenvector_matrix.data());
948 int leading_dimension = std::max(number_of_plane_waves, 1);
949 Complex alpha_one(1.0, 0.0), beta_zero(0.0, 0.0);
955 std::size_t collapsed_size =
static_cast<std::size_t
>(number_of_bands) *
956 static_cast<std::size_t
>(number_of_plane_waves);
960 basis_size * basis_size, device_backend_);
961 std::memcpy(device_eigenvector_matrix.
data(),
962 eigenvector_matrix.data(),
963 basis_size * basis_size *
sizeof(
Complex));
970 auto rotate_into_scratch = [&](
const Complex* source) {
973 number_of_plane_waves,
979 device_eigenvector_matrix.
data(),
984 device_backend_->synchronize();
987 rotate_into_scratch(basis_vectors);
988 std::memcpy(basis_vectors, rotation_scratch, collapsed_size *
sizeof(
Complex));
990 rotate_into_scratch(hamiltonian_basis_vectors);
991 std::memcpy(hamiltonian_basis_vectors, rotation_scratch, collapsed_size *
sizeof(
Complex));
1005 const bool overlap_needs_rotation =
1006 !is_identity_overlap || overlap_basis_vectors != basis_vectors;
1007 if (overlap_needs_rotation) {
1008 rotate_into_scratch(overlap_basis_vectors);
1009 std::memcpy(overlap_basis_vectors, rotation_scratch, collapsed_size *
sizeof(
Complex));
1012 enforce_gamma_g0_real(is_gamma_only, number_of_plane_waves, number_of_bands, basis_vectors);
1013 enforce_gamma_g0_real(
1014 is_gamma_only, number_of_plane_waves, number_of_bands, hamiltonian_basis_vectors);
1015 enforce_gamma_g0_real(
1016 is_gamma_only, number_of_plane_waves, number_of_bands, overlap_basis_vectors);
1018 return number_of_bands;