Skip to content

Commit 613a4ff

Browse files
committed
Fix(paged): fix PAGED_GPU dav_subspace issues: to_range() type-punning and cal_grad reference corruption
- psi.cpp to_range(): Range members are size_t but were bound to const int& references, causing (size_t)(-1) to be read as -1 via type punning. When nvec=0 (all bands converged), r2=nvec-1 wraps to SIZE_MAX, reads as -1 through int&, making r2<r1 true and triggering 'choose correct range of psi' error. Fixed by using size_t locals and checking sentinel index via i1>SIZE_MAX/2 instead of i1<0. - diago_dav_subspace.cpp cal_grad(): notconv parameter was a const int& reference to this->notconv. When all_zero=true inside cal_grad, this->notconv was set to 0, silently mutating the reference. The subsequent hpsi_func call at line 507 then used notconv=0, causing nvec=0, r2=(size_t)(-1), and CUBLAS ZGEMM parameter 10 error. Fixed by taking a local value copy to break the reference chain.
1 parent aaab6dd commit 613a4ff

2 files changed

Lines changed: 35 additions & 28 deletions

File tree

source/source_hsolver/diago_dav_subspace.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -279,17 +279,21 @@ int Diago_DavSubspace<T, Device>::diag_once(const HPsiFunc& hpsi_func,
279279

280280
template <typename T, typename Device>
281281
void Diago_DavSubspace<T, Device>::cal_grad(const HPsiFunc& hpsi_func,
282-
const HPsiFunc& spsi_func,
283-
const int& dim,
284-
const int& nbase,
285-
const int& notconv,
286-
T* psi_iter,
287-
T* hpsi,
288-
T* spsi,
289-
T* vcc,
290-
const int* unconv,
291-
std::vector<Real>* eigenvalue_iter)
282+
const HPsiFunc& spsi_func,
283+
const int& dim,
284+
const int& nbase,
285+
const int& notconv_ref,
286+
T* psi_iter,
287+
T* hpsi,
288+
T* spsi,
289+
T* vcc,
290+
const int* unconv,
291+
std::vector<Real>* eigenvalue_iter)
292292
{
293+
// Local copy: notconv_ref is a reference to this->notconv which may be
294+
// modified to 0 inside this function (all_zero path). We need the original
295+
// value for the remainder of the function.
296+
const int notconv = notconv_ref;
293297
ModuleBase::timer::start("Diago_DavSubspace", "cal_grad");
294298

295299
for (size_t i = 0; i < notconv; i++)

source/source_psi/psi.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -705,43 +705,46 @@ void Psi<T, Device>::zero_out()
705705
template <typename T, typename Device>
706706
std::tuple<const T*, int> Psi<T, Device>::to_range(const Range& range) const
707707
{
708-
const int& i1 = range.index_1;
709-
const int& r1 = range.range_1;
710-
const int& r2 = range.range_2;
711-
712-
if (range.k_first != this->k_first || r1 < 0
713-
|| r2 < r1
714-
// || (range.k_first && (r2 >= this->nbands || i1 >= this->nk))
715-
// || (!range.k_first && (r2 >= this->nk || i1 >= this->nbands)))
716-
|| (range.k_first ? (i1 >= this->nk) : (i1 >= this->nbands)) // illegal index 1
717-
|| (range.k_first ? (i1 > 0 && r2 >= this->nbands) : (i1 > 0 && r2 >= this->nk)) // illegal range of index 2
718-
|| (range.k_first ? (i1 < 0 && r2 >= this->nk) : (i1 < 0 && r2 >= this->nbands))) // illegal range of index 1
708+
const size_t i1 = range.index_1;
709+
const size_t r1 = range.range_1;
710+
const size_t r2 = range.range_2;
711+
712+
if (range.k_first != this->k_first || r2 < r1
713+
|| (range.k_first ? (i1 >= static_cast<size_t>(this->nk)) : (i1 >= static_cast<size_t>(this->nbands)))
714+
|| (range.k_first ? (i1 > 0 && r2 >= static_cast<size_t>(this->nbands)) : (i1 > 0 && r2 >= static_cast<size_t>(this->nk))))
719715
{
720716
return std::tuple<const T*, int>(nullptr, 0);
721717
}
722-
else if (i1 < 0) // [r1, r2] is the range of index1 with length m
718+
else if (i1 > static_cast<size_t>(std::numeric_limits<int>::max()))
723719
{
720+
// Sentinel case: i1 = (size_t)(-1) means a range of index1 (k-points)
721+
// For PAGED_GPU, this is not supported since GPU buffer is single-k
722+
if (storage_mode_ == PsiStorageMode::PAGED_GPU)
723+
{
724+
ModuleBase::WARNING_QUIT("Psi::to_range",
725+
"In PAGED_GPU mode, multi-k-point range is not supported");
726+
}
724727
const T* p = &this->psi[r1 * (k_first ? this->nbands : this->nk) * this->nbasis];
725-
int m = (r2 - r1 + 1) * this->get_npol();
728+
int m = static_cast<int>(r2 - r1 + 1) * this->get_npol();
726729
return std::tuple<const T*, int>(p, m);
727730
}
728-
else // [r1, r2] is the range of index2 with length m
731+
else // [r1, r2] is the range of band index for a specific k-point
729732
{
730733
if (storage_mode_ == PsiStorageMode::PAGED_GPU)
731734
{
732-
if (k_first && i1 != current_k)
735+
if (k_first && static_cast<int>(i1) != current_k)
733736
{
734737
ModuleBase::WARNING_QUIT("Psi::to_range",
735738
"In PAGED_GPU mode, requested k-point must match current_k");
736739
}
737-
const T* p = &this->psi[r1 * this->nbasis];
738-
int m = (r2 - r1 + 1) * this->get_npol();
740+
const T* p = &this->psi[static_cast<size_t>(r1) * static_cast<size_t>(this->nbasis)];
741+
int m = static_cast<int>(r2 - r1 + 1) * this->get_npol();
739742
return std::tuple<const T*, int>(p, m);
740743
}
741744
else
742745
{
743746
const T* p = &this->psi[(i1 * (k_first ? this->nbands : this->nk) + r1) * this->nbasis];
744-
int m = (r2 - r1 + 1) * this->get_npol();
747+
int m = static_cast<int>(r2 - r1 + 1) * this->get_npol();
745748
return std::tuple<const T*, int>(p, m);
746749
}
747750
}

0 commit comments

Comments
 (0)