Skip to content

Commit 0af2991

Browse files
authored
Merge branch 'develop' into dsp-link
2 parents f5f016a + 9cbcc0b commit 0af2991

120 files changed

Lines changed: 1652 additions & 1313 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/cuda.yml‎

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ name: CUDA Test
33
on:
44
workflow_dispatch:
55
pull_request:
6+
push:
7+
branches:
8+
- develop
69

710
defaults:
811
run:
@@ -19,10 +22,12 @@ jobs:
1922
if: github.repository_owner == 'deepmodeling'
2023
container:
2124
image: ghcr.io/deepmodeling/abacus-cuda
22-
volumes:
23-
- /tmp/ccache:/github/home/.ccache
2425
options: --gpus all
25-
26+
env:
27+
CCACHE_DIR: ${{ github.workspace }}/.ccache
28+
CCACHE_BASEDIR: ${{ github.workspace }}
29+
CCACHE_COMPRESS: "true"
30+
CCACHE_MAXSIZE: 8G
2631
steps:
2732
- name: Checkout
2833
uses: actions/checkout@v7.0.1
@@ -34,6 +39,26 @@ jobs:
3439
sudo apt-get update
3540
sudo apt-get install -y ccache xz-utils ninja-build pkg-config
3641
42+
- name: Calculate compiler cache fingerprint
43+
id: compiler
44+
run: |
45+
fingerprint="$({ c++ --version; nvcc --version; ccache --version; } | sha256sum | cut -d' ' -f1)"
46+
echo "fingerprint=${fingerprint}" >> "${GITHUB_OUTPUT}"
47+
48+
- name: Restore compiler cache
49+
uses: actions/cache@v4
50+
with:
51+
path: ${{ env.CCACHE_DIR }}
52+
key: abacus-cuda-ccache-v1-${{ runner.os }}-${{ runner.arch }}-${{ steps.compiler.outputs.fingerprint }}-${{ github.sha }}
53+
restore-keys: |
54+
abacus-cuda-ccache-v1-${{ runner.os }}-${{ runner.arch }}-${{ steps.compiler.outputs.fingerprint }}-
55+
56+
- name: Prepare compiler cache
57+
run: |
58+
mkdir -p "${CCACHE_DIR}"
59+
ccache --set-config="max_size=${CCACHE_MAXSIZE}"
60+
ccache --zero-stats
61+
3762
- name: Install external tools from toolchain
3863
run: |
3964
cd toolchain
@@ -51,6 +76,12 @@ jobs:
5176
cmake --build build -j "$(nproc)"
5277
cmake --install build
5378
79+
- name: Report compiler cache
80+
if: always()
81+
run: |
82+
ccache --show-stats
83+
ccache --show-stats >> "${GITHUB_STEP_SUMMARY}"
84+
5485
- name: Module_LCAO CUDA Unittests
5586
env:
5687
GTEST_COLOR: 'yes'

‎.github/workflows/interface.yml‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
prefix: Bi2Se3_pw
2525
basis: pw
2626
- name: advance (LCAO)
27-
script: example_advance.py
27+
script: example_advanced.py
2828
prefix: Bi2Se3_advanced
2929
basis: lcao
3030

@@ -58,12 +58,14 @@ jobs:
5858
env:
5959
SCRIPT: ${{ matrix.script }}
6060
PREFIX: ${{ matrix.prefix }}
61+
BASIS: ${{ matrix.basis }}
6162
run: |
6263
python3 << 'PYEOF'
6364
import os, re, textwrap
6465
6566
script = os.environ["SCRIPT"]
6667
prefix = os.environ["PREFIX"]
68+
basis = os.environ["BASIS"]
6769
6870
# ── 1. Patch the example script ────────────────────────
6971
with open(script) as f:
@@ -146,10 +148,12 @@ jobs:
146148
f" {nk}", "! num_kpts",
147149
" 4 4 4", "! mp_grid",
148150
]
151+
lines.append("begin kpoints")
149152
for ix in range(4):
150153
for iy in range(4):
151154
for iz in range(4):
152155
lines.append(f" {ix/4:.15f} {iy/4:.15f} {iz/4:.15f}")
156+
lines.append("end kpoints")
153157
154158
lines.append(f" {nntot}")
155159
lines.append("! nntot")

‎AGENTS.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,17 @@ The repository text files have been normalized to LF once. Day-to-day line
136136
ending enforcement should rely on staged/changed-file hooks and CI; rerun the
137137
full mixed-line-ending hook only for intentional repository-wide normalization.
138138

139+
## Upstream Repository
140+
141+
- Repository: https://github.com/deepmodeling/abacus-develop
142+
- Issues: https://github.com/deepmodeling/abacus-develop/issues
143+
- Pull requests: https://github.com/deepmodeling/abacus-develop/pulls
144+
- Upstream PRs are opened from personal fork branches
145+
(`<fork-owner>:<branch>` into `develop`).
146+
- `workflow_dispatch`-only workflows (e.g. `.github/workflows/interface.yml`)
147+
are not triggered by push/PR events; PR CI cannot verify such fixes, so
148+
state "manual dispatch run required" in the PR verification notes.
149+
139150
## PR Self-Check
140151

141152
- Confirm the PR body states exact commands run, whether they passed or failed,

‎source/CMakeLists.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,6 @@ target_link_libraries(
705705
psi_overall_init
706706
psi_init
707707
psi
708-
dftu
709708
deltaspin
710709
container
711710
device
@@ -721,6 +720,7 @@ if(ENABLE_LCAO)
721720
PRIVATE
722721
hamilt_lcao
723722
tddft
723+
dftu
724724
orb
725725
gint
726726
hcontainer

‎source/Makefile.Objects‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -840,8 +840,8 @@ OBJS_SRCPW=h_ewald_pw.o\
840840
update_cell_pw.o\
841841
dftu_base.o\
842842
dftu_base_io.o\
843-
dftu_base_occ.o\
844-
dftu_base_tools.o\
843+
dftu_pw.o\
844+
dftu_pw_tools.o\
845845
yukawa_screening.o\
846846
setup_dftu_pw.o\
847847
deltaspin_pw.o\

‎source/source_base/module_device/memory_op.cpp‎

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "memory_op.h"
22

33
#include "source_base/memory_recorder.h"
4+
#include "source_base/tool_quit.h"
45
#include "source_base/tool_threading.h"
56
#ifdef __DSP
67
#include "source_base/kernels/dsp/dsp_connector.h"
@@ -549,35 +550,52 @@ void set_memory(FPTYPE* arr, const int var, const size_t size, base_device::Abac
549550

550551
template <typename FPTYPE>
551552
void synchronize_memory(FPTYPE* arr_out, const FPTYPE* arr_in, const size_t size, base_device::AbacusDevice_t device_type_out, base_device::AbacusDevice_t device_type_in){
552-
if (device_type_out == base_device::AbacusDevice_t::CpuDevice || device_type_in == base_device::AbacusDevice_t::CpuDevice){
553+
// The four source/destination combinations are mutually exclusive, so each
554+
// branch must test BOTH devices. Using `||` here made the first branch match
555+
// whenever either side was the CPU, which routed host<->device transfers to
556+
// the host-to-host specialization.
557+
if (device_type_out == base_device::AbacusDevice_t::CpuDevice && device_type_in == base_device::AbacusDevice_t::CpuDevice){
553558
synchronize_memory_op<FPTYPE, DEVICE_CPU, DEVICE_CPU>()(arr_out, arr_in, size);
554559
}
555-
else if (device_type_out == base_device::AbacusDevice_t::CpuDevice || device_type_in == base_device::AbacusDevice_t::GpuDevice){
560+
#if __CUDA || __UT_USE_CUDA || __ROCM || __UT_USE_ROCM
561+
else if (device_type_out == base_device::AbacusDevice_t::CpuDevice && device_type_in == base_device::AbacusDevice_t::GpuDevice){
556562
synchronize_memory_op<FPTYPE, DEVICE_CPU, DEVICE_GPU>()(arr_out, arr_in, size);
557563
}
558-
else if (device_type_out == base_device::AbacusDevice_t::GpuDevice || device_type_in == base_device::AbacusDevice_t::CpuDevice){
564+
else if (device_type_out == base_device::AbacusDevice_t::GpuDevice && device_type_in == base_device::AbacusDevice_t::CpuDevice){
559565
synchronize_memory_op<FPTYPE, DEVICE_GPU, DEVICE_CPU>()(arr_out, arr_in, size);
560566
}
561-
else if (device_type_out == base_device::AbacusDevice_t::GpuDevice || device_type_in == base_device::AbacusDevice_t::GpuDevice){
567+
else if (device_type_out == base_device::AbacusDevice_t::GpuDevice && device_type_in == base_device::AbacusDevice_t::GpuDevice){
562568
synchronize_memory_op<FPTYPE, DEVICE_GPU, DEVICE_GPU>()(arr_out, arr_in, size);
563569
}
570+
#endif
571+
else {
572+
ModuleBase::WARNING_QUIT("base_device::memory::synchronize_memory",
573+
"unsupported source/destination device combination");
574+
}
564575
}
565576

566577
template <typename FPTYPE_out, typename FPTYPE_in>
567578
void cast_memory(FPTYPE_out* arr_out, const FPTYPE_in* arr_in, const size_t size, base_device::AbacusDevice_t device_type_out, base_device::AbacusDevice_t device_type_in)
568579
{
569-
if (device_type_out == base_device::AbacusDevice_t::CpuDevice || device_type_in == base_device::AbacusDevice_t::CpuDevice){
580+
// See synchronize_memory() above: dispatch on the exact (out, in) device pair.
581+
if (device_type_out == base_device::AbacusDevice_t::CpuDevice && device_type_in == base_device::AbacusDevice_t::CpuDevice){
570582
cast_memory_op<FPTYPE_out, FPTYPE_in, DEVICE_CPU, DEVICE_CPU>()(arr_out, arr_in, size);
571583
}
572-
else if (device_type_out == base_device::AbacusDevice_t::CpuDevice || device_type_in == base_device::AbacusDevice_t::GpuDevice){
584+
#if __CUDA || __UT_USE_CUDA || __ROCM || __UT_USE_ROCM
585+
else if (device_type_out == base_device::AbacusDevice_t::CpuDevice && device_type_in == base_device::AbacusDevice_t::GpuDevice){
573586
cast_memory_op<FPTYPE_out, FPTYPE_in, DEVICE_CPU, DEVICE_GPU>()(arr_out, arr_in, size);
574587
}
575-
else if (device_type_out == base_device::AbacusDevice_t::GpuDevice || device_type_in == base_device::AbacusDevice_t::CpuDevice){
588+
else if (device_type_out == base_device::AbacusDevice_t::GpuDevice && device_type_in == base_device::AbacusDevice_t::CpuDevice){
576589
cast_memory_op<FPTYPE_out, FPTYPE_in, DEVICE_GPU, DEVICE_CPU>()(arr_out, arr_in, size);
577590
}
578-
else if (device_type_out == base_device::AbacusDevice_t::GpuDevice || device_type_in == base_device::AbacusDevice_t::GpuDevice){
591+
else if (device_type_out == base_device::AbacusDevice_t::GpuDevice && device_type_in == base_device::AbacusDevice_t::GpuDevice){
579592
cast_memory_op<FPTYPE_out, FPTYPE_in, DEVICE_GPU, DEVICE_GPU>()(arr_out, arr_in, size);
580593
}
594+
#endif
595+
else {
596+
ModuleBase::WARNING_QUIT("base_device::memory::cast_memory",
597+
"unsupported source/destination device combination");
598+
}
581599
}
582600

583601
template <typename FPTYPE>
@@ -591,5 +609,24 @@ void delete_memory(FPTYPE* arr, base_device::AbacusDevice_t device_type)
591609
}
592610
}
593611

612+
// Explicit instantiations of the runtime-dispatch wrappers, so that the
613+
// declarations in memory_op.h can actually be linked from another translation
614+
// unit (and covered by unit tests). cast_memory is instantiated only for the
615+
// type pairs that cast_memory_op provides for all four device combinations.
616+
template void synchronize_memory<int>(int*, const int*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
617+
template void synchronize_memory<float>(float*, const float*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
618+
template void synchronize_memory<double>(double*, const double*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
619+
template void synchronize_memory<std::complex<float>>(std::complex<float>*, const std::complex<float>*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
620+
template void synchronize_memory<std::complex<double>>(std::complex<double>*, const std::complex<double>*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
621+
622+
template void cast_memory<float, float>(float*, const float*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
623+
template void cast_memory<double, double>(double*, const double*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
624+
template void cast_memory<float, double>(float*, const double*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
625+
template void cast_memory<double, float>(double*, const float*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
626+
template void cast_memory<std::complex<float>, std::complex<float>>(std::complex<float>*, const std::complex<float>*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
627+
template void cast_memory<std::complex<double>, std::complex<double>>(std::complex<double>*, const std::complex<double>*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
628+
template void cast_memory<std::complex<float>, std::complex<double>>(std::complex<float>*, const std::complex<double>*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
629+
template void cast_memory<std::complex<double>, std::complex<float>>(std::complex<double>*, const std::complex<float>*, const size_t, base_device::AbacusDevice_t, base_device::AbacusDevice_t);
630+
594631
} // namespace memory
595632
} // namespace base_device

‎source/source_base/module_device/test/memory_test.cpp‎

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,59 @@ TEST_F(TestModulePsiMemory, delete_memory_op_complex_double_cpu)
170170
delete_memory_complex_double_cpu_op()(hz_xx);
171171
}
172172

173+
// ---------------------------------------------------------------------------
174+
// Runtime-dispatch wrappers (issue #7553).
175+
//
176+
// synchronize_memory()/cast_memory() pick a compile-time specialization from a
177+
// pair of runtime AbacusDevice_t values. The branches used to be joined with
178+
// `||`, so the first one matched whenever EITHER side was the CPU and every
179+
// host<->device transfer was served by the host-to-host specialization. The
180+
// checks below pin the exact-pair dispatch for all combinations available in
181+
// the current build.
182+
// ---------------------------------------------------------------------------
183+
184+
TEST_F(TestModulePsiMemory, synchronize_memory_dispatch_cpu_to_cpu)
185+
{
186+
std::vector<double> h_xx(xx.size(), 0);
187+
base_device::memory::synchronize_memory(h_xx.data(),
188+
xx.data(),
189+
xx.size(),
190+
base_device::AbacusDevice_t::CpuDevice,
191+
base_device::AbacusDevice_t::CpuDevice);
192+
for (int ii = 0; ii < xx.size(); ii++)
193+
{
194+
EXPECT_EQ(h_xx[ii], xx[ii]);
195+
}
196+
}
197+
198+
TEST_F(TestModulePsiMemory, synchronize_memory_dispatch_complex_cpu_to_cpu)
199+
{
200+
std::vector<std::complex<double>> hz_xx(z_xx.size(), std::complex<double>(0, 0));
201+
base_device::memory::synchronize_memory(hz_xx.data(),
202+
z_xx.data(),
203+
z_xx.size(),
204+
base_device::AbacusDevice_t::CpuDevice,
205+
base_device::AbacusDevice_t::CpuDevice);
206+
for (int ii = 0; ii < z_xx.size(); ii++)
207+
{
208+
EXPECT_EQ(hz_xx[ii], z_xx[ii]);
209+
}
210+
}
211+
212+
TEST_F(TestModulePsiMemory, cast_memory_dispatch_cpu_to_cpu)
213+
{
214+
std::vector<float> h_xx(xx.size(), 0);
215+
base_device::memory::cast_memory(h_xx.data(),
216+
xx.data(),
217+
xx.size(),
218+
base_device::AbacusDevice_t::CpuDevice,
219+
base_device::AbacusDevice_t::CpuDevice);
220+
for (int ii = 0; ii < xx.size(); ii++)
221+
{
222+
EXPECT_FLOAT_EQ(h_xx[ii], static_cast<float>(xx[ii]));
223+
}
224+
}
225+
173226
#if __UT_USE_CUDA || __UT_USE_ROCM
174227
TEST_F(TestModulePsiMemory, set_memory_op_double_gpu)
175228
{
@@ -347,4 +400,90 @@ TEST_F(TestModulePsiMemory, delete_memory_op_complex_double_gpu)
347400
delete_memory_complex_double_gpu_op()(thrust::raw_pointer_cast(dz_xx));
348401
}
349402

403+
404+
// Exact-pair dispatch across the host/device boundary (issue #7553). Before the
405+
// fix these three cases all reached synchronize_memory_op<..., CPU, CPU>, i.e. a
406+
// plain host memcpy on a device pointer.
407+
TEST_F(TestModulePsiMemory, synchronize_memory_dispatch_cpu_to_gpu)
408+
{
409+
thrust::device_ptr<double> d_xx = thrust::device_malloc<double>(xx.size());
410+
std::vector<double> hv_xx(xx.size(), 0);
411+
thrust::copy(hv_xx.begin(), hv_xx.end(), d_xx);
412+
base_device::memory::synchronize_memory(thrust::raw_pointer_cast(d_xx),
413+
xx.data(),
414+
xx.size(),
415+
base_device::AbacusDevice_t::GpuDevice,
416+
base_device::AbacusDevice_t::CpuDevice);
417+
418+
thrust::host_vector<double> h_xx(xx.size());
419+
thrust::copy(d_xx, d_xx + xx.size(), h_xx.begin());
420+
for (int ii = 0; ii < xx.size(); ii++)
421+
{
422+
EXPECT_EQ(h_xx[ii], xx[ii]);
423+
}
424+
thrust::device_free(d_xx);
425+
}
426+
427+
TEST_F(TestModulePsiMemory, synchronize_memory_dispatch_gpu_to_cpu)
428+
{
429+
thrust::device_ptr<double> d_xx = thrust::device_malloc<double>(xx.size());
430+
thrust::copy(xx.begin(), xx.end(), d_xx);
431+
thrust::host_vector<double> h_xx(xx.size());
432+
base_device::memory::synchronize_memory(thrust::raw_pointer_cast(h_xx.data()),
433+
thrust::raw_pointer_cast(d_xx),
434+
xx.size(),
435+
base_device::AbacusDevice_t::CpuDevice,
436+
base_device::AbacusDevice_t::GpuDevice);
437+
438+
for (int ii = 0; ii < xx.size(); ii++)
439+
{
440+
EXPECT_EQ(h_xx[ii], xx[ii]);
441+
}
442+
thrust::device_free(d_xx);
443+
}
444+
445+
TEST_F(TestModulePsiMemory, synchronize_memory_dispatch_gpu_to_gpu)
446+
{
447+
thrust::device_ptr<double> d1_xx = thrust::device_malloc<double>(xx.size());
448+
thrust::device_ptr<double> d2_xx = thrust::device_malloc<double>(xx.size());
449+
thrust::copy(xx.begin(), xx.end(), d1_xx);
450+
base_device::memory::synchronize_memory(thrust::raw_pointer_cast(d2_xx),
451+
thrust::raw_pointer_cast(d1_xx),
452+
xx.size(),
453+
base_device::AbacusDevice_t::GpuDevice,
454+
base_device::AbacusDevice_t::GpuDevice);
455+
456+
thrust::host_vector<double> h_xx(xx.size());
457+
thrust::copy(d2_xx, d2_xx + xx.size(), h_xx.begin());
458+
for (int ii = 0; ii < xx.size(); ii++)
459+
{
460+
EXPECT_EQ(h_xx[ii], xx[ii]);
461+
}
462+
thrust::device_free(d1_xx);
463+
thrust::device_free(d2_xx);
464+
}
465+
466+
TEST_F(TestModulePsiMemory, cast_memory_dispatch_cpu_to_gpu_and_back)
467+
{
468+
thrust::device_ptr<float> d_xx = thrust::device_malloc<float>(xx.size());
469+
base_device::memory::cast_memory(thrust::raw_pointer_cast(d_xx),
470+
xx.data(),
471+
xx.size(),
472+
base_device::AbacusDevice_t::GpuDevice,
473+
base_device::AbacusDevice_t::CpuDevice);
474+
475+
std::vector<double> h_xx(xx.size(), 0);
476+
base_device::memory::cast_memory(h_xx.data(),
477+
thrust::raw_pointer_cast(d_xx),
478+
xx.size(),
479+
base_device::AbacusDevice_t::CpuDevice,
480+
base_device::AbacusDevice_t::GpuDevice);
481+
482+
for (int ii = 0; ii < xx.size(); ii++)
483+
{
484+
EXPECT_FLOAT_EQ(static_cast<float>(h_xx[ii]), static_cast<float>(xx[ii]));
485+
}
486+
thrust::device_free(d_xx);
487+
}
488+
350489
#endif // __UT_USE_CUDA || __UT_USE_ROCM

0 commit comments

Comments
 (0)