Skip to content

Commit cc06269

Browse files
Critsium-xyzxy.monado
andauthored
Fix GPU nonmagnetic spinor charge accumulation (#7902)
Co-authored-by: zxy.monado <zxy.monado@bytedance.com>
1 parent 42c6184 commit cc06269

4 files changed

Lines changed: 72 additions & 10 deletions

File tree

source/source_estate/kernels/cuda/elecstate_op.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ __global__ void elecstate_pw(
5252
rho[3 * nrxx_dense + idx] += w1 * (norm(wfcr[idx]) - norm(wfcr_another_spin[idx]));
5353
}
5454
else {
55-
rho[0 * nrxx_dense + idx] = 0;
55+
// Keep the scalar charge accumulated above; only magnetization is disabled.
5656
rho[1 * nrxx_dense + idx] = 0;
5757
rho[2 * nrxx_dense + idx] = 0;
5858
rho[3 * nrxx_dense + idx] = 0;
@@ -103,4 +103,4 @@ void elecstate_pw_op<FPTYPE, base_device::DEVICE_GPU>::operator()(const base_dev
103103
template struct elecstate_pw_op<float, base_device::DEVICE_GPU>;
104104
template struct elecstate_pw_op<double, base_device::DEVICE_GPU>;
105105

106-
} // namespace elecstate
106+
} // namespace elecstate

source/source_estate/kernels/rocm/elecstate_op.hip.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ __global__ void elecstate_pw(
5050
rho[3 * nrxx + idx] += w1 * (norm(wfcr[idx]) - norm(wfcr_another_spin[idx]));
5151
}
5252
else {
53-
rho[0 * nrxx + idx] = 0;
53+
// Keep the scalar charge accumulated above; only magnetization is disabled.
5454
rho[1 * nrxx + idx] = 0;
5555
rho[2 * nrxx + idx] = 0;
5656
rho[3 * nrxx + idx] = 0;
@@ -96,4 +96,4 @@ void elecstate_pw_op<FPTYPE, base_device::DEVICE_GPU>::operator()(const base_dev
9696

9797
template struct elecstate_pw_op<float, base_device::DEVICE_GPU>;
9898
template struct elecstate_pw_op<double, base_device::DEVICE_GPU>;
99-
}
99+
}

source/source_estate/kernels/test/elecstate_op_test.cpp

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ TEST_F(TestModuleElecstateMultiDevice, elecstate_pw_op_gpu)
129129
EXPECT_LT(fabs(rho_data[ii] - expected_rho[ii]), 6e-5);
130130
}
131131
delete [] rho;
132-
delete_memory_var_op()(this->gpu_ctx, d_rho_data);
133-
delete_memory_complex_op()(this->gpu_ctx, d_wfcr);
132+
delete_memory_var_op()(d_rho_data);
133+
delete_memory_complex_op()(d_wfcr);
134134
}
135135

136136
TEST_F(TestModuleElecstateMultiDevice, elecstate_pw_spin_op_gpu)
@@ -168,9 +168,65 @@ TEST_F(TestModuleElecstateMultiDevice, elecstate_pw_spin_op_gpu)
168168
EXPECT_LT(fabs(rho_data_2[ii] - expected_rho_2[ii]), 5e-4);
169169
}
170170
delete [] rho;
171-
delete_memory_var_op()(this->gpu_ctx, d_rho_data_2);
172-
delete_memory_complex_op()(this->gpu_ctx, d_wfcr_2);
173-
delete_memory_complex_op()(this->gpu_ctx, d_wfcr_another_spin_2);
171+
delete_memory_var_op()(d_rho_data_2);
172+
delete_memory_complex_op()(d_wfcr_2);
173+
delete_memory_complex_op()(d_wfcr_another_spin_2);
174174
}
175-
#endif // __CUDA || __UT_USE_CUDA || __ROCM || __UT_USE_ROCM
176175

176+
TEST_F(TestModuleElecstateMultiDevice, nonmagnetic_spinor_preserves_charge_on_gpu)
177+
{
178+
const int nrxx = 2;
179+
const double weight = 0.5;
180+
const bool domag = false;
181+
const bool domag_z = false;
182+
const std::vector<std::complex<double>> wfcr = {{1.0, 0.0}, {0.0, 2.0}};
183+
const std::vector<std::complex<double>> wfcr_another_spin = {{0.0, 1.0}, {3.0, 0.0}};
184+
std::vector<double> rho_cpu = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
185+
std::vector<double> rho_gpu = rho_cpu;
186+
double* rho_cpu_components[4]
187+
= {rho_cpu.data(), rho_cpu.data() + nrxx, rho_cpu.data() + 2 * nrxx, rho_cpu.data() + 3 * nrxx};
188+
189+
elecstate_cpu_op()(this->cpu_ctx,
190+
domag,
191+
domag_z,
192+
nrxx,
193+
nrxx,
194+
weight,
195+
rho_cpu_components,
196+
wfcr.data(),
197+
wfcr_another_spin.data());
198+
199+
double* rho_device = nullptr;
200+
std::complex<double>* wfcr_device = nullptr;
201+
std::complex<double>* wfcr_another_spin_device = nullptr;
202+
resize_memory_var_op()(rho_device, rho_gpu.size());
203+
resize_memory_complex_op()(wfcr_device, wfcr.size());
204+
resize_memory_complex_op()(wfcr_another_spin_device, wfcr_another_spin.size());
205+
syncmem_var_h2d_op()(rho_device, rho_gpu.data(), rho_gpu.size());
206+
syncmem_complex_h2d_op()(wfcr_device, wfcr.data(), wfcr.size());
207+
syncmem_complex_h2d_op()(wfcr_another_spin_device, wfcr_another_spin.data(), wfcr_another_spin.size());
208+
double* rho_gpu_components[4] = {rho_device, rho_device + nrxx, rho_device + 2 * nrxx, rho_device + 3 * nrxx};
209+
210+
elecstate_gpu_op()(this->gpu_ctx,
211+
domag,
212+
domag_z,
213+
nrxx,
214+
nrxx,
215+
weight,
216+
rho_gpu_components,
217+
wfcr_device,
218+
wfcr_another_spin_device);
219+
syncmem_var_d2h_op()(rho_gpu.data(), rho_device, rho_gpu.size());
220+
221+
EXPECT_DOUBLE_EQ(rho_cpu[0], 2.0);
222+
EXPECT_DOUBLE_EQ(rho_cpu[1], 8.5);
223+
for (std::size_t ir = 0; ir < rho_cpu.size(); ++ir)
224+
{
225+
EXPECT_DOUBLE_EQ(rho_gpu[ir], rho_cpu[ir]);
226+
}
227+
228+
delete_memory_var_op()(rho_device);
229+
delete_memory_complex_op()(wfcr_device);
230+
delete_memory_complex_op()(wfcr_another_spin_device);
231+
}
232+
#endif // __CUDA || __UT_USE_CUDA || __ROCM || __UT_USE_ROCM

source/source_estate/test/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ AddTest(
1717
SOURCES ../kernels/test/elecstate_op_test.cpp
1818
)
1919

20+
if(USE_CUDA)
21+
target_compile_definitions(MODULE_ESTATE_Elecstate_Op_UTs PRIVATE __UT_USE_CUDA)
22+
elseif(USE_ROCM)
23+
target_compile_definitions(MODULE_ESTATE_Elecstate_Op_UTs PRIVATE __UT_USE_ROCM)
24+
endif()
25+
2026
AddTest(
2127
TARGET MODULE_ESTATE_elecstate_occupy
2228
LIBS parameter base device

0 commit comments

Comments
 (0)