Skip to content

Commit 3baec1f

Browse files
dyzhengclaude
andcommitted
fix: add npol==1 branch to GPU/DCU DFT+U onsite_ps_op kernels
The CUDA and ROCm kernels for the DFT+U onsite_ps_op only had npol==2 (nspin=4) logic. When npol==1 (nspin=1/2), the kernel would access out-of-bounds memory (ps[psind+1], becp[becpind+tnp], and non-existent vu matrix blocks). This mirrors the CPU fix in commit 65b738a. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 65b738a commit 3baec1f

2 files changed

Lines changed: 82 additions & 36 deletions

File tree

source/source_pw/module_pwdft/kernels/cuda/onsite_op.cu

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,49 @@ __global__ void onsite_op(const int npm,
4848
int m1 = ip_m[ip];
4949
if (m1 >= 0)
5050
{
51-
const int nbands = npm / npol;
52-
for (int ib = threadIdx.x; ib < nbands; ib += blockDim.x)
51+
if (npol == 2)
5352
{
54-
int ib2 = ib * npol;
55-
int iat = ip_iat[ip];
56-
const thrust::complex<FPTYPE>* vu_iat = vu + vu_begin_iat[iat];
57-
int orb_l = orb_l_iat[iat];
58-
int tlp1 = 2 * orb_l + 1;
59-
int tlp1_2 = tlp1 * tlp1;
60-
int ip2_begin = ip - m1;
61-
int ip2_end = ip - m1 + tlp1;
62-
const int psind = ip * npm + ib2;
63-
for (int ip2 = ip2_begin; ip2 < ip2_end; ip2++)
53+
const int nbands = npm / npol;
54+
for (int ib = threadIdx.x; ib < nbands; ib += blockDim.x)
6455
{
65-
const int becpind = ib2 * tnp + ip2;
66-
int m2 = ip_m[ip2];
67-
const int index_mm = m1 * tlp1 + m2;
68-
ps[psind] += vu_iat[index_mm] * becp[becpind] + vu_iat[index_mm + tlp1_2 * 2] * becp[becpind + tnp];
69-
ps[psind + 1] += vu_iat[index_mm + tlp1_2 * 1] * becp[becpind]
70-
+ vu_iat[index_mm + tlp1_2 * 3] * becp[becpind + tnp];
56+
int ib2 = ib * npol;
57+
int iat = ip_iat[ip];
58+
const thrust::complex<FPTYPE>* vu_iat = vu + vu_begin_iat[iat];
59+
int orb_l = orb_l_iat[iat];
60+
int tlp1 = 2 * orb_l + 1;
61+
int tlp1_2 = tlp1 * tlp1;
62+
int ip2_begin = ip - m1;
63+
int ip2_end = ip - m1 + tlp1;
64+
const int psind = ip * npm + ib2;
65+
for (int ip2 = ip2_begin; ip2 < ip2_end; ip2++)
66+
{
67+
const int becpind = ib2 * tnp + ip2;
68+
int m2 = ip_m[ip2];
69+
const int index_mm = m1 * tlp1 + m2;
70+
ps[psind] += vu_iat[index_mm] * becp[becpind] + vu_iat[index_mm + tlp1_2 * 2] * becp[becpind + tnp];
71+
ps[psind + 1] += vu_iat[index_mm + tlp1_2 * 1] * becp[becpind]
72+
+ vu_iat[index_mm + tlp1_2 * 3] * becp[becpind + tnp];
73+
}
74+
}
75+
}
76+
else // npol == 1, nspin=1 or nspin=2
77+
{
78+
for (int ib = threadIdx.x; ib < npm; ib += blockDim.x)
79+
{
80+
int iat = ip_iat[ip];
81+
const thrust::complex<FPTYPE>* vu_iat = vu + vu_begin_iat[iat];
82+
int orb_l = orb_l_iat[iat];
83+
int tlp1 = 2 * orb_l + 1;
84+
int ip2_begin = ip - m1;
85+
int ip2_end = ip - m1 + tlp1;
86+
const int psind = ip * npm + ib;
87+
for (int ip2 = ip2_begin; ip2 < ip2_end; ip2++)
88+
{
89+
const int becpind = ib * tnp + ip2;
90+
int m2 = ip_m[ip2];
91+
const int index_mm = m1 * tlp1 + m2;
92+
ps[psind] += vu_iat[index_mm] * becp[becpind];
93+
}
7194
}
7295
}
7396
}

source/source_pw/module_pwdft/kernels/rocm/onsite_op.hip.cu

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,49 @@ __global__ void onsite_op(const int npm,
4848
int m1 = ip_m[ip];
4949
if (m1 >= 0)
5050
{
51-
const int nbands = npm / npol;
52-
for (int ib = threadIdx.x; ib < nbands; ib += blockDim.x)
51+
if (npol == 2)
5352
{
54-
int ib2 = ib * npol;
55-
int iat = ip_iat[ip];
56-
const thrust::complex<FPTYPE>* vu_iat = vu + vu_begin_iat[iat];
57-
int orb_l = orb_l_iat[iat];
58-
int tlp1 = 2 * orb_l + 1;
59-
int tlp1_2 = tlp1 * tlp1;
60-
int ip2_begin = ip - m1;
61-
int ip2_end = ip - m1 + tlp1;
62-
const int psind = ip * npm + ib2;
63-
for (int ip2 = ip2_begin; ip2 < ip2_end; ip2++)
53+
const int nbands = npm / npol;
54+
for (int ib = threadIdx.x; ib < nbands; ib += blockDim.x)
6455
{
65-
const int becpind = ib2 * tnp + ip2;
66-
int m2 = ip_m[ip2];
67-
const int index_mm = m1 * tlp1 + m2;
68-
ps[psind] += vu_iat[index_mm] * becp[becpind] + vu_iat[index_mm + tlp1_2 * 2] * becp[becpind + tnp];
69-
ps[psind + 1] += vu_iat[index_mm + tlp1_2 * 1] * becp[becpind]
70-
+ vu_iat[index_mm + tlp1_2 * 3] * becp[becpind + tnp];
56+
int ib2 = ib * npol;
57+
int iat = ip_iat[ip];
58+
const thrust::complex<FPTYPE>* vu_iat = vu + vu_begin_iat[iat];
59+
int orb_l = orb_l_iat[iat];
60+
int tlp1 = 2 * orb_l + 1;
61+
int tlp1_2 = tlp1 * tlp1;
62+
int ip2_begin = ip - m1;
63+
int ip2_end = ip - m1 + tlp1;
64+
const int psind = ip * npm + ib2;
65+
for (int ip2 = ip2_begin; ip2 < ip2_end; ip2++)
66+
{
67+
const int becpind = ib2 * tnp + ip2;
68+
int m2 = ip_m[ip2];
69+
const int index_mm = m1 * tlp1 + m2;
70+
ps[psind] += vu_iat[index_mm] * becp[becpind] + vu_iat[index_mm + tlp1_2 * 2] * becp[becpind + tnp];
71+
ps[psind + 1] += vu_iat[index_mm + tlp1_2 * 1] * becp[becpind]
72+
+ vu_iat[index_mm + tlp1_2 * 3] * becp[becpind + tnp];
73+
}
74+
}
75+
}
76+
else // npol == 1, nspin=1 or nspin=2
77+
{
78+
for (int ib = threadIdx.x; ib < npm; ib += blockDim.x)
79+
{
80+
int iat = ip_iat[ip];
81+
const thrust::complex<FPTYPE>* vu_iat = vu + vu_begin_iat[iat];
82+
int orb_l = orb_l_iat[iat];
83+
int tlp1 = 2 * orb_l + 1;
84+
int ip2_begin = ip - m1;
85+
int ip2_end = ip - m1 + tlp1;
86+
const int psind = ip * npm + ib;
87+
for (int ip2 = ip2_begin; ip2 < ip2_end; ip2++)
88+
{
89+
const int becpind = ib * tnp + ip2;
90+
int m2 = ip_m[ip2];
91+
const int index_mm = m1 * tlp1 + m2;
92+
ps[psind] += vu_iat[index_mm] * becp[becpind];
93+
}
7194
}
7295
}
7396
}

0 commit comments

Comments
 (0)