Skip to content

Commit 8f7c2c7

Browse files
author
njzjz-bot
committed
chore: merge master into fix-paddle-download-hash
Bring the pull request up to date with the current base branch. Coding-Agent: Codex Codex-Version: codex-cli 0.144.6 Model: gpt-5.6-sol Reasoning-Effort: xhigh
2 parents e9e2eae + 4f827cc commit 8f7c2c7

68 files changed

Lines changed: 4266 additions & 1594 deletions

Some content is hidden

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

.github/workflows/test_cuda.yml

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,13 @@ jobs:
1919
runs-on: gpu
2020
# The serial Python test suite can take several hours on the GPU runner.
2121
timeout-minutes: 480
22-
# Share ONE AOTInductor on-disk compile cache across the two pytest lanes;
23-
# actions/cache (below) persists it across runs so unchanged models never
24-
# recompile.
25-
env:
26-
TORCHINDUCTOR_CACHE_DIR: ${{ github.workspace }}/.inductor-cache
2722
# https://github.com/deepmodeling/deepmd-kit/pull/2884#issuecomment-1744216845
2823
# container:
2924
# image: nvidia/cuda:12.9.1-cudnn-devel-ubuntu22.04
3025
# options: --gpus all
3126
if: github.repository_owner == 'deepmodeling' && (github.event_name == 'pull_request' && github.event.label && github.event.label.name == 'Test CUDA' || github.event_name == 'workflow_dispatch' || github.event_name == 'merge_group')
3227
steps:
3328
- uses: actions/checkout@v7
34-
- name: Cache AOTInductor compile artifacts
35-
# Restored AFTER checkout so checkout's git-clean can't wipe it. The repo
36-
# Actions cache is capped at 10 GB; if the inductor cache outgrows it the
37-
# oldest entries are evicted -- correctness is unaffected (inductor
38-
# re-validates each graph; a miss just recompiles).
39-
uses: actions/cache@v6
40-
with:
41-
path: ${{ github.workspace }}/.inductor-cache
42-
key: inductor-cuda-${{ github.sha }}
43-
restore-keys: |
44-
inductor-cuda-
4529
- uses: actions/setup-python@v7
4630
with:
4731
python-version: "3.11"
@@ -78,84 +62,23 @@ jobs:
7862
DP_ENABLE_NATIVE_OPTIMIZATION: 1
7963
DP_ENABLE_PYTORCH: 1
8064
- run: dp --version
81-
- name: Run Python tests (overlap CPU-bound aoti compiles with the GPU lane)
82-
# Two pytest lanes on one GPU box:
83-
# Lane 1 (CPU stream): the .pt2-freezing tests (-m aoti_compile) --
84-
# CPU-bound, GPU ~98% idle while inductor/g++/ptxas run.
85-
# Lane 2 (GPU stream): the GPU-bound remainder (-m "not aoti_compile")
86-
# -- the bulk of the suite and the wall-clock bottleneck. It does not
87-
# freeze .pt2, so it only reads the inductor cache, never competing
88-
# to write.
89-
# Wall-clock becomes max(lane 1, lane 2) instead of their sum; the whole
90-
# compile stream is hidden behind the GPU lane. (The C++ build + fixture
91-
# generation runs in the separate test_cc job.)
92-
run: |
93-
# Cap the compile lane's inductor threads to ~half the cores so lane 2
94-
# keeps CPU for its host-side GPU dispatch; nice the compile work too.
95-
nc=$(( $(nproc) / 2 )); [ "$nc" -lt 1 ] && nc=1
96-
# rc=0 + `|| rc=$?` so a lane's failure does not let the step's default
97-
# `set -e` skip the wall-clock echo (the timing we most want on failure).
98-
( ta=$(date +%s); rc=0
99-
TORCHINDUCTOR_COMPILE_THREADS=$nc nice -n 15 \
100-
python -m pytest source/tests -m "aoti_compile" \
101-
-p no:cacheprovider --junit-xml=junit-aoti.xml || rc=$?
102-
# pytest exit 5 == "no tests collected"; harmless for the compile lane.
103-
[ "$rc" = 5 ] && rc=0
104-
echo "[lane aoti_compile] wall=$(( $(date +%s) - ta ))s exit=$rc"
105-
exit $rc ) &
106-
pid_a=$!
107-
( tb=$(date +%s); rc=0
108-
python -m pytest source/tests -m "not aoti_compile" \
109-
-p no:cacheprovider --junit-xml=junit-gpu.xml || rc=$?
110-
echo "[lane gpu] wall=$(( $(date +%s) - tb ))s exit=$rc"
111-
exit $rc ) &
112-
pid_b=$!
113-
rc_a=0; wait $pid_a || rc_a=$?
114-
rc_b=0; wait $pid_b || rc_b=$?
115-
echo "lane exit codes: aoti_compile=$rc_a gpu=$rc_b"
116-
exit $(( rc_a != 0 || rc_b != 0 ))
65+
- run: python -m pytest source/tests
11766
env:
11867
NUM_WORKERS: 0
11968
CUDA_VISIBLE_DEVICES: 0
12069
# See https://jax.readthedocs.io/en/latest/gpu_memory_allocation.html
12170
XLA_PYTHON_CLIENT_PREALLOCATE: false
12271
XLA_PYTHON_CLIENT_ALLOCATOR: platform
12372
FLAGS_use_stride_compute_kernel: 0
124-
- name: Upload per-lane JUnit reports
125-
# junit-aoti.xml = compile lane (T_A), junit-gpu.xml = GPU lane (T_B);
126-
# used to compare the two lanes against the pre-split serial baseline.
127-
if: always()
128-
uses: actions/upload-artifact@v7
129-
with:
130-
name: cuda-pytest-junit
131-
path: |
132-
junit-aoti.xml
133-
junit-gpu.xml
134-
if-no-files-found: warn
13573

13674
test_cc:
13775
name: Test C++ on CUDA
13876
runs-on: gpu
139-
# The gen_*.py fixture builds drive the same AOTInductor backend on the same
140-
# architectures as the Python lanes, so they reuse the kernels cached by
141-
# test_python / previous runs.
142-
env:
143-
TORCHINDUCTOR_CACHE_DIR: ${{ github.workspace }}/.inductor-cache
14477
if: github.repository_owner == 'deepmodeling' && (github.event_name == 'pull_request' && github.event.label && github.event.label.name == 'Test CUDA' || github.event_name == 'workflow_dispatch' || github.event_name == 'merge_group')
14578
steps:
14679
# Jobs run on separate runners, so the C++ job needs its own complete
14780
# CUDA toolchain and Python dependency installation.
14881
- uses: actions/checkout@v7
149-
- name: Cache AOTInductor compile artifacts
150-
# Restored AFTER checkout so checkout's git-clean can't wipe it. Both
151-
# CUDA jobs share the same key; if both try to save it, the second save
152-
# is skipped with a warning (caches are immutable), which is harmless.
153-
uses: actions/cache@v6
154-
with:
155-
path: ${{ github.workspace }}/.inductor-cache
156-
key: inductor-cuda-${{ github.sha }}
157-
restore-keys: |
158-
inductor-cuda-
15982
- uses: actions/setup-python@v7
16083
with:
16184
python-version: "3.11"

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ repos:
3030
exclude: ^source/3rdparty
3131
- repo: https://github.com/astral-sh/ruff-pre-commit
3232
# Ruff version.
33-
rev: v0.15.22
33+
rev: v0.16.0
3434
hooks:
3535
- id: ruff
3636
args: ["--fix"]

deepmd/dpmodel/atomic_model/base_atomic_model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ def change_out_bias(
758758
delta_bias, out_std = compute_output_stats(
759759
sample_merged,
760760
self.get_ntypes(),
761-
keys=list(self.atomic_output_def().keys()),
761+
keys=self.bias_keys,
762762
stat_file_path=stat_file_path,
763763
model_forward=self._get_forward_wrapper_func(),
764764
rcond=self.rcond,
@@ -771,7 +771,7 @@ def change_out_bias(
771771
bias_out, std_out = compute_output_stats(
772772
sample_merged,
773773
self.get_ntypes(),
774-
keys=list(self.atomic_output_def().keys()),
774+
keys=self.bias_keys,
775775
stat_file_path=stat_file_path,
776776
rcond=self.rcond,
777777
preset_bias=self.preset_out_bias,

deepmd/dpmodel/descriptor/descriptor.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,37 @@ def get_stats(self) -> dict[str, StatItem]:
110110
"""Get the statistics of the descriptor."""
111111
raise NotImplementedError
112112

113+
def set_stat_mean_and_stddev(
114+
self,
115+
mean: Array,
116+
stddev: Array,
117+
) -> None:
118+
"""Update the normalization arrays of the descriptor block.
119+
120+
Parameters
121+
----------
122+
mean
123+
Mean of the environment matrix.
124+
stddev
125+
Standard deviation of the environment matrix.
126+
127+
Returns
128+
-------
129+
None
130+
"""
131+
self["davg"] = mean
132+
self["dstd"] = stddev
133+
134+
def get_stat_mean_and_stddev(self) -> tuple[Array, Array]:
135+
"""Return the normalization arrays of the descriptor block.
136+
137+
Returns
138+
-------
139+
tuple[Array, Array]
140+
Mean and standard deviation of the environment matrix.
141+
"""
142+
return self["davg"], self["dstd"]
143+
113144
def share_params(
114145
self, base_class: Any, shared_level: Any, resume: bool = False
115146
) -> None:

deepmd/dpmodel/descriptor/dpa1.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,15 +1461,7 @@ def compute_input_stats(
14611461
env_mat_stat = EnvMatStatSe(self, use_graph=True)
14621462
if path is not None:
14631463
path = path / env_mat_stat.get_hash()
1464-
if path is None or not path.is_dir():
1465-
if callable(merged):
1466-
# only get data for once
1467-
sampled = merged()
1468-
else:
1469-
sampled = merged
1470-
else:
1471-
sampled = []
1472-
env_mat_stat.load_or_compute_stats(sampled, path)
1464+
env_mat_stat.load_or_compute_stats(merged, path)
14731465
self.stats = env_mat_stat.stats
14741466
mean, stddev = env_mat_stat()
14751467
xp = array_api_compat.array_namespace(self.stddev)

deepmd/dpmodel/descriptor/repflows.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -494,15 +494,7 @@ def compute_input_stats(
494494
env_mat_stat = EnvMatStatSe(self)
495495
if path is not None:
496496
path = path / env_mat_stat.get_hash()
497-
if path is None or not path.is_dir():
498-
if callable(merged):
499-
# only get data for once
500-
sampled = merged()
501-
else:
502-
sampled = merged
503-
else:
504-
sampled = []
505-
env_mat_stat.load_or_compute_stats(sampled, path)
497+
env_mat_stat.load_or_compute_stats(merged, path)
506498
self.stats = env_mat_stat.stats
507499
mean, stddev = env_mat_stat()
508500
xp = array_api_compat.array_namespace(self.stddev)

deepmd/dpmodel/descriptor/repformers.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -459,15 +459,7 @@ def compute_input_stats(
459459
env_mat_stat = EnvMatStatSe(self)
460460
if path is not None:
461461
path = path / env_mat_stat.get_hash()
462-
if path is None or not path.is_dir():
463-
if callable(merged):
464-
# only get data for once
465-
sampled = merged()
466-
else:
467-
sampled = merged
468-
else:
469-
sampled = []
470-
env_mat_stat.load_or_compute_stats(sampled, path)
462+
env_mat_stat.load_or_compute_stats(merged, path)
471463
self.stats = env_mat_stat.stats
472464
mean, stddev = env_mat_stat()
473465
xp = array_api_compat.array_namespace(self.stddev)

deepmd/dpmodel/descriptor/se_e2_a.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -349,15 +349,7 @@ def compute_input_stats(
349349
env_mat_stat = EnvMatStatSe(self)
350350
if path is not None:
351351
path = path / env_mat_stat.get_hash()
352-
if path is None or not path.is_dir():
353-
if callable(merged):
354-
# only get data for once
355-
sampled = merged()
356-
else:
357-
sampled = merged
358-
else:
359-
sampled = []
360-
env_mat_stat.load_or_compute_stats(sampled, path)
352+
env_mat_stat.load_or_compute_stats(merged, path)
361353
self.stats = env_mat_stat.stats
362354
mean, stddev = env_mat_stat()
363355
xp = array_api_compat.array_namespace(self.dstd)

deepmd/dpmodel/descriptor/se_r.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -328,15 +328,7 @@ def compute_input_stats(
328328
env_mat_stat = EnvMatStatSe(self)
329329
if path is not None:
330330
path = path / env_mat_stat.get_hash()
331-
if path is None or not path.is_dir():
332-
if callable(merged):
333-
# only get data for once
334-
sampled = merged()
335-
else:
336-
sampled = merged
337-
else:
338-
sampled = []
339-
env_mat_stat.load_or_compute_stats(sampled, path)
331+
env_mat_stat.load_or_compute_stats(merged, path)
340332
self.stats = env_mat_stat.stats
341333
mean, stddev = env_mat_stat()
342334
xp = array_api_compat.array_namespace(self.dstd)

deepmd/dpmodel/descriptor/se_t.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -303,15 +303,7 @@ def compute_input_stats(
303303
env_mat_stat = EnvMatStatSe(self)
304304
if path is not None:
305305
path = path / env_mat_stat.get_hash()
306-
if path is None or not path.is_dir():
307-
if callable(merged):
308-
# only get data for once
309-
sampled = merged()
310-
else:
311-
sampled = merged
312-
else:
313-
sampled = []
314-
env_mat_stat.load_or_compute_stats(sampled, path)
306+
env_mat_stat.load_or_compute_stats(merged, path)
315307
self.stats = env_mat_stat.stats
316308
mean, stddev = env_mat_stat()
317309
xp = array_api_compat.array_namespace(self.dstd)

0 commit comments

Comments
 (0)