11#! /bin/bash
22set -ex
33
4+ # Phase gating (default: run everything, so existing callers like test_cc.yml
5+ # are unaffected). The CUDA workflow splits the CPU-bound build+fixture-gen
6+ # from the GPU-bound ctest so the former can overlap the Python GPU tests:
7+ # DP_CC_SKIP_CTEST=1 -> configure + build + install + gen fixtures, no ctest
8+ # DP_CC_SKIP_BUILD=1 -> skip build/gen, run only ctest on the built tree
9+ DP_CC_SKIP_BUILD=${DP_CC_SKIP_BUILD:- 0}
10+ DP_CC_SKIP_CTEST=${DP_CC_SKIP_CTEST:- 0}
11+
412if [ " $DP_VARIANT " = " cuda" ]; then
513 CUDA_ARGS=" -DUSE_CUDA_TOOLKIT=TRUE"
614elif [ " $DP_VARIANT " = " rocm" ]; then
@@ -20,27 +28,37 @@ BUILD_TMP_DIR=${SCRIPT_PATH}/../build_tests
2028PADDLE_INFERENCE_DIR=${BUILD_TMP_DIR} /paddle_inference_install_dir
2129mkdir -p ${BUILD_TMP_DIR}
2230cd ${BUILD_TMP_DIR}
23- cmake \
24- -D ENABLE_TENSORFLOW=${ENABLE_TENSORFLOW:- TRUE} \
25- -D ENABLE_PYTORCH=${ENABLE_PYTORCH:- TRUE} \
26- -D ENABLE_PADDLE=${ENABLE_PADDLE:- TRUE} \
27- -D INSTALL_TENSORFLOW=FALSE \
28- -D USE_TF_PYTHON_LIBS=${ENABLE_TENSORFLOW:- TRUE} \
29- -D USE_PT_PYTHON_LIBS=${ENABLE_PYTORCH:- TRUE} \
30- -D CMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \
31- -D BUILD_TESTING:BOOL=TRUE \
32- -D LAMMPS_VERSION=stable_22Jul2025_update2 \
33- ${CUDA_ARGS} ..
34- cmake --build . -j${NPROC}
35- cmake --install .
36- # Generate PT/PT2 model files for C++ tests.
37- # Must run after cmake --build so that libdeepmd_op_pt.so (custom ops) is available.
38- if [ " ${ENABLE_PYTORCH:- TRUE} " == " TRUE" ]; then
39- # Install the custom op .so to SHARED_LIB_DIR so that `import deepmd.pt`
40- # loads it via cxx_op.py. The .so depends on libdeepmd.so (compute
41- # kernels) in the install prefix, so add that to LD_LIBRARY_PATH too.
42- export LD_LIBRARY_PATH=${INSTALL_PREFIX} /lib:${LD_LIBRARY_PATH}
43- python -c '
31+
32+ # LD_LIBRARY_PATH additions needed by BOTH the gen scripts (which import
33+ # deepmd.pt and dlopen the custom op .so that depends on libdeepmd.so in the
34+ # install prefix) AND ctest. Set once up front so either phase works alone.
35+ # The install prefix may not exist yet during the build; a missing dir in
36+ # LD_LIBRARY_PATH is harmless.
37+ export LD_LIBRARY_PATH=${INSTALL_PREFIX} /lib:${LD_LIBRARY_PATH}
38+ if [ " ${ENABLE_PADDLE:- TRUE} " == " TRUE" ]; then
39+ export LD_LIBRARY_PATH=${LD_LIBRARY_PATH} :${PADDLE_INFERENCE_DIR} /third_party/install/onednn/lib:${PADDLE_INFERENCE_DIR} /third_party/install/mklml/lib
40+ fi
41+
42+ if [ " ${DP_CC_SKIP_BUILD} " != " 1" ]; then
43+ cmake \
44+ -D ENABLE_TENSORFLOW=${ENABLE_TENSORFLOW:- TRUE} \
45+ -D ENABLE_PYTORCH=${ENABLE_PYTORCH:- TRUE} \
46+ -D ENABLE_PADDLE=${ENABLE_PADDLE:- TRUE} \
47+ -D INSTALL_TENSORFLOW=FALSE \
48+ -D USE_TF_PYTHON_LIBS=${ENABLE_TENSORFLOW:- TRUE} \
49+ -D USE_PT_PYTHON_LIBS=${ENABLE_PYTORCH:- TRUE} \
50+ -D CMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \
51+ -D BUILD_TESTING:BOOL=TRUE \
52+ -D LAMMPS_VERSION=stable_22Jul2025_update2 \
53+ ${CUDA_ARGS} ..
54+ cmake --build . -j${NPROC}
55+ cmake --install .
56+ # Generate PT/PT2 model files for C++ tests.
57+ # Must run after cmake --build so that libdeepmd_op_pt.so (custom ops) is available.
58+ if [ " ${ENABLE_PYTORCH:- TRUE} " == " TRUE" ]; then
59+ # Install the custom op .so to SHARED_LIB_DIR so that `import deepmd.pt`
60+ # loads it via cxx_op.py.
61+ python -c '
4462import shutil, sys
4563from pathlib import Path
4664from deepmd.env import SHARED_LIB_DIR
@@ -55,67 +73,67 @@ else:
5573 shutil.copy2(str(so), str(dst))
5674 print(f"Installed {so} -> {dst}")
5775'
58- # When the build uses -fsanitize=leak, the custom op .so requires the LSAN
59- # runtime to be preloaded (otherwise dlopen fails). We disable leak detection
60- # in the gen scripts to avoid false reports from torch/paddle internals.
61- INFER_SCRIPT_PATH=${SCRIPT_PATH} /../tests/infer
62- # Remove stale generated model files so they can't be accidentally reused
63- # if gen scripts change format or the code version changes.
64- rm -f ${INFER_SCRIPT_PATH} /* .pt2 ${INFER_SCRIPT_PATH} /* .pte
65- _GEN_ENV=" "
66- if echo " ${CXXFLAGS:- } " | grep -q fsanitize=leak; then
67- _LSAN_LIB=$( gcc -print-file-name=liblsan.so 2> /dev/null || true)
68- if [ -n " ${_LSAN_LIB} " ] && [ -f " ${_LSAN_LIB} " ]; then
69- # DP_GEN_UNDER_SANITIZER: explicit signal for gen scripts that need
70- # to skip sanitizer-incompatible sections (e.g. gen_dpa2.py's
71- # AOTInductor graph .pt2 eval, which can SEGV under the LSAN
72- # runtime). Sniffing LD_PRELOAD inside the gen script is NOT
73- # reliable: the sanitizer runtime removes its own entry from the
74- # process environment during startup.
75- _GEN_ENV=" LD_PRELOAD=${_LSAN_LIB} LSAN_OPTIONS=detect_leaks=0 DP_GEN_UNDER_SANITIZER=lsan"
76+ # When the build uses -fsanitize=leak, the custom op .so requires the LSAN
77+ # runtime to be preloaded (otherwise dlopen fails). We disable leak detection
78+ # in the gen scripts to avoid false reports from torch/paddle internals.
79+ INFER_SCRIPT_PATH=${SCRIPT_PATH} /../tests/infer
80+ # Remove stale generated model files so they can't be accidentally reused
81+ # if gen scripts change format or the code version changes.
82+ rm -f ${INFER_SCRIPT_PATH} /* .pt2 ${INFER_SCRIPT_PATH} /* .pte
83+ _GEN_ENV=" "
84+ if echo " ${CXXFLAGS:- } " | grep -q fsanitize=leak; then
85+ _LSAN_LIB=$( gcc -print-file-name=liblsan.so 2> /dev/null || true)
86+ if [ -n " ${_LSAN_LIB} " ] && [ -f " ${_LSAN_LIB} " ]; then
87+ # DP_GEN_UNDER_SANITIZER: explicit signal for gen scripts that need
88+ # to skip sanitizer-incompatible sections (e.g. gen_dpa2.py's
89+ # AOTInductor graph .pt2 eval, which can SEGV under the LSAN
90+ # runtime). Sniffing LD_PRELOAD inside the gen script is NOT
91+ # reliable: the sanitizer runtime removes its own entry from the
92+ # process environment during startup.
93+ _GEN_ENV=" LD_PRELOAD=${_LSAN_LIB} LSAN_OPTIONS=detect_leaks=0 DP_GEN_UNDER_SANITIZER=lsan"
94+ fi
7695 fi
77- fi
78- # Run gen scripts in parallel for faster model generation.
79- # Wait on each PID separately so any failure is caught by set -e.
80- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_sea.py &
81- PID1=$!
82- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa1.py &
83- PID2=$!
84- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa2.py &
85- PID3=$!
86- wait $PID1
87- wait $PID2
88- wait $PID3
96+ # Run gen scripts in parallel for faster model generation.
97+ # Wait on each PID separately so any failure is caught by set -e.
98+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_sea.py &
99+ PID1=$!
100+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa1.py &
101+ PID2=$!
102+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa2.py &
103+ PID3=$!
104+ wait $PID1
105+ wait $PID2
106+ wait $PID3
89107
90- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa3.py &
91- PID4=$!
92- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_fparam_aparam.py &
93- PID5=$!
94- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_model_devi.py &
95- PID6=$!
96- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_chg_spin.py &
97- PID9=$!
98- wait $PID4
99- wait $PID5
100- wait $PID6
101- wait $PID9
108+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa3.py &
109+ PID4=$!
110+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_fparam_aparam.py &
111+ PID5=$!
112+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_model_devi.py &
113+ PID6=$!
114+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_chg_spin.py &
115+ PID9=$!
116+ wait $PID4
117+ wait $PID5
118+ wait $PID6
119+ wait $PID9
102120
103- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa4.py &
104- PID9=$!
105- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa1_pairexcl.py &
106- PID10=$!
107- wait $PID9
108- wait $PID10
121+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa4.py &
122+ PID9=$!
123+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_dpa1_pairexcl.py &
124+ PID10=$!
125+ wait $PID9
126+ wait $PID10
109127
110- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_spin.py &
111- PID7=$!
112- env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_spin_model_devi.py &
113- PID8=$!
114- wait $PID7
115- wait $PID8
128+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_spin.py &
129+ PID7=$!
130+ env ${_GEN_ENV} python ${INFER_SCRIPT_PATH} /gen_spin_model_devi.py &
131+ PID8=$!
132+ wait $PID7
133+ wait $PID8
134+ fi
116135fi
117- if [ " ${ENABLE_PADDLE :- TRUE} " == " TRUE " ] ; then
118- PADDLE_INFERENCE_DIR= ${BUILD_TMP_DIR} /paddle_inference_install_dir
119- export LD_LIBRARY_PATH= ${LD_LIBRARY_PATH} : ${PADDLE_INFERENCE_DIR} /third_party/install/onednn/lib: ${PADDLE_INFERENCE_DIR} /third_party/install/mklml/lib
136+
137+ if [ " ${DP_CC_SKIP_CTEST} " != " 1 " ] ; then
138+ ctest --output-on-failure
120139fi
121- ctest --output-on-failure
0 commit comments