From ff6a93147dd86f2174d5e251ebe24377cc59d1d4 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 29 Apr 2026 21:33:55 +0800 Subject: [PATCH 1/7] fix(dpmodel): align NativeLayer bias/idt init with pt MLPLayer dpmodel's NativeLayer used Glorot scaling (1/sqrt(num_in+num_out)) for w, b, and idt, while pt's MLPLayer._default_normal_init uses Glorot only for w and instead uses N(0, 1) for bias and N(0.1, 0.001) for idt. The mismatch persists through training (Adam preserves per-parameter scale) and produces ~15-20% worse validation RMSE on multi-task DPA3 (verified on debug/260426_test_compile_multitask: e_alloy 1.51e-2 -> 1.79e-2, f_alloy 1.39e-1 -> 1.49e-1, e_elec 1.13e-3 -> 1.32e-3, f_elec 4.58e-2 -> 5.53e-2). Affects every dpmodel-based backend (pt_expt, jax, paddle). --- deepmd/dpmodel/utils/network.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/deepmd/dpmodel/utils/network.py b/deepmd/dpmodel/utils/network.py index ff46c5787d..e93e46782f 100644 --- a/deepmd/dpmodel/utils/network.py +++ b/deepmd/dpmodel/utils/network.py @@ -117,15 +117,16 @@ def __init__( # only use_timestep when skip connection is established. use_timestep = use_timestep and (num_out == num_in or num_out == num_in * 2) rng = np.random.default_rng(seed) - scale_factor = 1.0 / np.sqrt(num_out + num_in) - self.w = rng.normal(size=(num_in, num_out), scale=scale_factor).astype(prec) - self.b = ( - rng.normal(size=(num_out,), scale=scale_factor).astype(prec) - if bias - else None - ) + # Match deepmd/pt MLPLayer._default_normal_init: w uses Glorot scaling, + # but b is N(0, 1) (unscaled) and idt is N(0.1, 0.001). Using Glorot + # scaling for b/idt empirically slows convergence on ResNet-style + # fitting nets because residual layers start near identity (idt~0). + self.w = rng.normal( + size=(num_in, num_out), scale=1.0 / np.sqrt(num_out + num_in) + ).astype(prec) + self.b = rng.normal(size=(num_out,), scale=1.0).astype(prec) if bias else None self.idt = ( - rng.normal(size=(num_out,), scale=scale_factor).astype(prec) + (rng.normal(size=(num_out,), scale=0.001) + 0.1).astype(prec) if use_timestep else None ) From 35d5cb21d253238a8215082710de0d66cd7cadf2 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 30 Apr 2026 16:03:25 +0800 Subject: [PATCH 2/7] test: replace hardcoded C++ expected values with sidecar reference files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each `gen_*.py` script writes a plain-text `.expected` file alongside the .pt2/.pth model files; C++ tests load the arrays at SetUp() via a new `ExpectedRef` helper instead of carrying ~3000 magic-number floats baked into the test sources. This removes the manual paste-from-stdout sync that broke whenever dpmodel numerics shifted (e.g., the bias/idt init alignment in ff6a9314), and keeps reference values in lockstep with the gen scripts that produce them. - New `source/api_cc/tests/expected_ref.h` (header-only loader) - New `gen_common.write_expected_ref()` writer; `print_cpp_values` and `print_cpp_spin_values` retained as ad-hoc debug helpers - 7 gen scripts (dpa1/2/3, spin, fparam_aparam, model_devi) emit sidecars - 15 C++ tests load arrays from sidecars (no test cases removed) - `test_deeppot_ptexpt.cc` keeps its TF-derived hardcoded refs (its model weights flow through `gen_fparam_aparam.py`'s state_dict load path, not random init, so they're stable) - Bump float32 atol from 1e-5 to 4e-5 in `test_compressed_forward` for DPA1 / SeAttenV2: the new bias init scale widens the embedding-net output range, observed compression-tabulation error ~3.2e-5 - `.expected` files are gitignored — regenerated at CI time --- .gitignore | 1 + source/api_cc/tests/expected_ref.h | 93 ++++++++++ ..._deeppot_a_fparam_aparam_nframes_ptexpt.cc | 113 +++--------- .../tests/test_deeppot_a_fparam_aparam_pt.cc | 64 ++----- .../test_deeppot_a_fparam_aparam_ptexpt.cc | 61 ++----- .../tests/test_deeppot_default_fparam_pt.cc | 52 ++---- .../test_deeppot_default_fparam_ptexpt.cc | 65 ++----- source/api_cc/tests/test_deeppot_dpa1_pt.cc | 123 ++++--------- .../api_cc/tests/test_deeppot_dpa1_ptexpt.cc | 119 +++---------- source/api_cc/tests/test_deeppot_dpa2_pt.cc | 124 ++++--------- .../api_cc/tests/test_deeppot_dpa2_ptexpt.cc | 118 +++---------- source/api_cc/tests/test_deeppot_dpa3_pt.cc | 124 ++++--------- .../api_cc/tests/test_deeppot_dpa3_ptexpt.cc | 118 +++---------- .../api_cc/tests/test_deeppot_dpa_pt_spin.cc | 167 ++++-------------- .../api_cc/tests/test_deeppot_dpa_ptexpt.cc | 118 +++---------- .../tests/test_deeppot_dpa_ptexpt_spin.cc | 130 +++----------- .../tests/test_deeppot_model_devi_ptexpt.cc | 16 +- source/tests/infer/gen_common.py | 58 +++++- source/tests/infer/gen_dpa1.py | 24 ++- source/tests/infer/gen_dpa2.py | 24 ++- source/tests/infer/gen_dpa3.py | 24 ++- source/tests/infer/gen_fparam_aparam.py | 91 ++++------ source/tests/infer/gen_model_devi.py | 71 ++------ source/tests/infer/gen_spin.py | 28 ++- source/tests/pt_expt/descriptor/test_dpa1.py | 6 +- .../pt_expt/descriptor/test_se_atten_v2.py | 6 +- 26 files changed, 664 insertions(+), 1274 deletions(-) create mode 100644 source/api_cc/tests/expected_ref.h diff --git a/.gitignore b/.gitignore index 12b149c911..897a224371 100644 --- a/.gitignore +++ b/.gitignore @@ -73,3 +73,4 @@ frozen_model.* # Test system directories system/ +*.expected diff --git a/source/api_cc/tests/expected_ref.h b/source/api_cc/tests/expected_ref.h new file mode 100644 index 0000000000..332bea164b --- /dev/null +++ b/source/api_cc/tests/expected_ref.h @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace deepmd_test { + +// Loader for sidecar reference files written by +// `gen_common.write_expected_ref`. +// +// File format: +// # auto-generated -- do not edit +// [case_name_1] +// array_name_1 N +// v0 +// v1 +// ... +// array_name_2 M +// ... +// +// [case_name_2] +// ... +// +// Lines beginning with '#' or empty lines are ignored. +class ExpectedRef { + public: + // Parse `path`. Throws std::runtime_error on malformed input. + void load(const std::string& path) { + std::ifstream in(path); + if (!in) { + throw std::runtime_error("ExpectedRef: cannot open " + path); + } + sections_.clear(); + std::string line; + std::string current_section; + while (std::getline(in, line)) { + if (line.empty() || line[0] == '#') { + continue; + } + if (line.front() == '[' && line.back() == ']') { + current_section = line.substr(1, line.size() - 2); + continue; + } + // " " header — followed by `count` numeric lines. + if (current_section.empty()) { + throw std::runtime_error("ExpectedRef: array '" + line + + "' before any [section]"); + } + std::istringstream iss(line); + std::string key; + std::size_t n = 0; + if (!(iss >> key >> n)) { + throw std::runtime_error("ExpectedRef: bad header line: " + line); + } + std::vector values; + values.reserve(n); + for (std::size_t i = 0; i < n; ++i) { + if (!std::getline(in, line)) { + throw std::runtime_error("ExpectedRef: unexpected EOF in '" + key + + "'"); + } + values.push_back(std::stod(line)); + } + sections_[current_section][key] = std::move(values); + } + } + + // Get array of `key` from `case_name`. Throws if missing. + template + std::vector get(const std::string& case_name, + const std::string& key) const { + auto sit = sections_.find(case_name); + if (sit == sections_.end()) { + throw std::runtime_error("ExpectedRef: missing case '" + case_name + "'"); + } + auto kit = sit->second.find(key); + if (kit == sit->second.end()) { + throw std::runtime_error("ExpectedRef: missing array '" + key + + "' in case '" + case_name + "'"); + } + return std::vector(kit->second.begin(), kit->second.end()); + } + + private: + std::map>> sections_; +}; + +} // namespace deepmd_test diff --git a/source/api_cc/tests/test_deeppot_a_fparam_aparam_nframes_ptexpt.cc b/source/api_cc/tests/test_deeppot_a_fparam_aparam_nframes_ptexpt.cc index c72b210f7c..ac5fec08a4 100644 --- a/source/api_cc/tests/test_deeppot_a_fparam_aparam_nframes_ptexpt.cc +++ b/source/api_cc/tests/test_deeppot_a_fparam_aparam_nframes_ptexpt.cc @@ -9,8 +9,14 @@ #include "DeepPot.h" #include "DeepPotPTExpt.h" +#include "expected_ref.h" #include "test_utils.h" +namespace { +constexpr const char* kRefPath = "../../tests/infer/fparam_aparam.expected"; +constexpr const char* kModelPath = "../../tests/infer/fparam_aparam.pt2"; +} // namespace + template class TestInferDeepPotAFparamAparamNFramesPtExpt : public ::testing::Test { protected: @@ -27,88 +33,9 @@ class TestInferDeepPotAFparamAparamNFramesPtExpt : public ::testing::Test { std::vector aparam = { 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028}; - // Same reference values as single-frame, duplicated for 2 frames - std::vector expected_e = { - -1.038271223729636539e-01, -7.285433579124989123e-02, - -9.467600492266425860e-02, -1.467050207422957442e-01, - -7.660561676973243195e-02, -7.277296000253175023e-02, - -1.038271223729636539e-01, -7.285433579124989123e-02, - -9.467600492266425860e-02, -1.467050207422957442e-01, - -7.660561676973243195e-02, -7.277296000253175023e-02}; - std::vector expected_f = { - 6.622266941151369601e-02, 5.278739714221529489e-02, - 2.265728009692277028e-02, -2.606048291367509331e-02, - -4.538812303131847109e-02, 1.058247419681241676e-02, - 1.679392617013223121e-01, -2.257826240741929533e-03, - -4.490146347357203138e-02, -1.148364179422036724e-01, - -1.169790528013799069e-02, 6.140403441496700837e-02, - -8.078778123309421355e-02, -5.838879041789352825e-02, - 6.773641084621376263e-02, -1.247724902386305318e-02, - 6.494524782787665373e-02, -1.174787360813439457e-01, - 6.622266941151369601e-02, 5.278739714221529489e-02, - 2.265728009692277028e-02, -2.606048291367509331e-02, - -4.538812303131847109e-02, 1.058247419681241676e-02, - 1.679392617013223121e-01, -2.257826240741929533e-03, - -4.490146347357203138e-02, -1.148364179422036724e-01, - -1.169790528013799069e-02, 6.140403441496700837e-02, - -8.078778123309421355e-02, -5.838879041789352825e-02, - 6.773641084621376263e-02, -1.247724902386305318e-02, - 6.494524782787665373e-02, -1.174787360813439457e-01}; - std::vector expected_v = { - -1.589185601903579381e-01, 2.586167090689088510e-03, - -1.575150812458056548e-04, -1.855360549216640564e-02, - 1.949822308966445150e-02, -1.006552178977542650e-02, - 3.177030388421490936e-02, 1.714350280402104215e-03, - -1.290389705296313833e-03, -8.553511587973079699e-02, - -5.654638208496251539e-03, -1.286955066237439882e-02, - 2.464156699303176462e-02, -2.398203243424212178e-02, - -1.957110698882909630e-02, 2.233493653505165544e-02, - 6.107843889444162372e-03, 1.707076397717688723e-03, - -1.653994136896924094e-01, 3.894358809712639147e-02, - -2.169596032233910010e-02, 6.819702786556020371e-03, - -5.018240707559744503e-03, 2.640663592968431426e-03, - -1.985295554050418160e-03, -3.638422207618969423e-02, - 2.342932709960221863e-02, -8.501331666888653493e-02, - -2.181253119706856591e-03, 4.311299629418858387e-03, - -1.910329576491436726e-03, -1.808810428459609043e-03, - -1.540075460017477360e-03, -1.173703527688202929e-02, - -2.596307050960845741e-03, 6.705026635782097323e-03, - -9.038454847872562370e-02, 3.011717694088476838e-02, - -5.083053967307901710e-02, -2.951212926932282599e-03, - 2.342446057919112673e-02, -4.091208178777860222e-02, - -1.648470670751139844e-02, -2.872262362355524484e-02, - 4.763925761561256522e-02, -8.300037376164930147e-02, - 1.020429200603871836e-03, -1.026734257188876599e-03, - 5.678534821710372327e-02, 1.273635858276599142e-02, - -1.530143401888291177e-02, -1.061672032476311256e-01, - -2.486859787145567074e-02, 2.875323543588798395e-02, - -1.589185601903579381e-01, 2.586167090689088510e-03, - -1.575150812458056548e-04, -1.855360549216640564e-02, - 1.949822308966445150e-02, -1.006552178977542650e-02, - 3.177030388421490936e-02, 1.714350280402104215e-03, - -1.290389705296313833e-03, -8.553511587973079699e-02, - -5.654638208496251539e-03, -1.286955066237439882e-02, - 2.464156699303176462e-02, -2.398203243424212178e-02, - -1.957110698882909630e-02, 2.233493653505165544e-02, - 6.107843889444162372e-03, 1.707076397717688723e-03, - -1.653994136896924094e-01, 3.894358809712639147e-02, - -2.169596032233910010e-02, 6.819702786556020371e-03, - -5.018240707559744503e-03, 2.640663592968431426e-03, - -1.985295554050418160e-03, -3.638422207618969423e-02, - 2.342932709960221863e-02, -8.501331666888653493e-02, - -2.181253119706856591e-03, 4.311299629418858387e-03, - -1.910329576491436726e-03, -1.808810428459609043e-03, - -1.540075460017477360e-03, -1.173703527688202929e-02, - -2.596307050960845741e-03, 6.705026635782097323e-03, - -9.038454847872562370e-02, 3.011717694088476838e-02, - -5.083053967307901710e-02, -2.951212926932282599e-03, - 2.342446057919112673e-02, -4.091208178777860222e-02, - -1.648470670751139844e-02, -2.872262362355524484e-02, - 4.763925761561256522e-02, -8.300037376164930147e-02, - 1.020429200603871836e-03, -1.026734257188876599e-03, - 5.678534821710372327e-02, 1.273635858276599142e-02, - -1.530143401888291177e-02, -1.061672032476311256e-01, - -2.486859787145567074e-02, 2.875323543588798395e-02}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; int nframes = 2; std::vector expected_tot_e; @@ -118,7 +45,7 @@ class TestInferDeepPotAFparamAparamNFramesPtExpt : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/fparam_aparam.pt2"); + dp.init(kModelPath); #endif } @@ -126,14 +53,26 @@ class TestInferDeepPotAFparamAparamNFramesPtExpt : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + auto e_single = ref.get("default", "expected_e"); + auto f_single = ref.get("default", "expected_f"); + auto v_single = ref.get("default", "expected_v"); + // Replicate single-frame reference for nframes batched inference. + expected_e.reserve(nframes * e_single.size()); + expected_f.reserve(nframes * f_single.size()); + expected_v.reserve(nframes * v_single.size()); + for (int kk = 0; kk < nframes; ++kk) { + expected_e.insert(expected_e.end(), e_single.begin(), e_single.end()); + expected_f.insert(expected_f.end(), f_single.begin(), f_single.end()); + expected_v.insert(expected_v.end(), v_single.begin(), v_single.end()); + } natoms = expected_e.size() / nframes; EXPECT_EQ(nframes * natoms * 3, expected_f.size()); EXPECT_EQ(nframes * natoms * 9, expected_v.size()); - expected_tot_e.resize(nframes); - expected_tot_v.resize(static_cast(nframes) * 9); - std::fill(expected_tot_e.begin(), expected_tot_e.end(), 0.); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_e.assign(nframes, 0.); + expected_tot_v.assign(static_cast(nframes) * 9, 0.); for (int kk = 0; kk < nframes; ++kk) { for (int ii = 0; ii < natoms; ++ii) { expected_tot_e[kk] += expected_e[kk * natoms + ii]; diff --git a/source/api_cc/tests/test_deeppot_a_fparam_aparam_pt.cc b/source/api_cc/tests/test_deeppot_a_fparam_aparam_pt.cc index c8569ec212..442a2c1b6d 100644 --- a/source/api_cc/tests/test_deeppot_a_fparam_aparam_pt.cc +++ b/source/api_cc/tests/test_deeppot_a_fparam_aparam_pt.cc @@ -10,6 +10,7 @@ #include #include "DeepPot.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -17,6 +18,11 @@ #undef EPSILON #define EPSILON (std::is_same::value ? 1e-7 : 1e-4) +namespace { +constexpr const char* kRefPath = "../../tests/infer/fparam_aparam.expected"; +constexpr const char* kModelPath = "../../tests/infer/fparam_aparam.pth"; +} // namespace + template class TestInferDeepPotAFParamAParamPt : public ::testing::Test { protected: @@ -28,50 +34,9 @@ class TestInferDeepPotAFParamAParamPt : public ::testing::Test { std::vector fparam = {0.25852028}; std::vector aparam = {0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028}; - // Generated by source/tests/infer/gen_fparam_aparam.py - // (from pre-committed fparam_aparam_default.pth, type_one_side=True) - std::vector expected_e = { - -1.038271223729636539e-01, -7.285433579124989123e-02, - -9.467600492266425860e-02, -1.467050207422957442e-01, - -7.660561676973243195e-02, -7.277296000253175023e-02}; - std::vector expected_f = { - 6.622266941151369601e-02, 5.278739714221529489e-02, - 2.265728009692277028e-02, -2.606048291367509331e-02, - -4.538812303131847109e-02, 1.058247419681241676e-02, - 1.679392617013223121e-01, -2.257826240741929533e-03, - -4.490146347357203138e-02, -1.148364179422036724e-01, - -1.169790528013799069e-02, 6.140403441496700837e-02, - -8.078778123309421355e-02, -5.838879041789352825e-02, - 6.773641084621376263e-02, -1.247724902386305318e-02, - 6.494524782787665373e-02, -1.174787360813439457e-01}; - std::vector expected_v = { - -1.589185601903579381e-01, 2.586167090689088510e-03, - -1.575150812458056548e-04, -1.855360549216640564e-02, - 1.949822308966445150e-02, -1.006552178977542650e-02, - 3.177030388421490936e-02, 1.714350280402104215e-03, - -1.290389705296313833e-03, -8.553511587973079699e-02, - -5.654638208496251539e-03, -1.286955066237439882e-02, - 2.464156699303176462e-02, -2.398203243424212178e-02, - -1.957110698882909630e-02, 2.233493653505165544e-02, - 6.107843889444162372e-03, 1.707076397717688723e-03, - -1.653994136896924094e-01, 3.894358809712639147e-02, - -2.169596032233910010e-02, 6.819702786556020371e-03, - -5.018240707559744503e-03, 2.640663592968431426e-03, - -1.985295554050418160e-03, -3.638422207618969423e-02, - 2.342932709960221863e-02, -8.501331666888653493e-02, - -2.181253119706856591e-03, 4.311299629418858387e-03, - -1.910329576491436726e-03, -1.808810428459609043e-03, - -1.540075460017477360e-03, -1.173703527688202929e-02, - -2.596307050960845741e-03, 6.705026635782097323e-03, - -9.038454847872562370e-02, 3.011717694088476838e-02, - -5.083053967307901710e-02, -2.951212926932282599e-03, - 2.342446057919112673e-02, -4.091208178777860222e-02, - -1.648470670751139844e-02, -2.872262362355524484e-02, - 4.763925761561256522e-02, -8.300037376164930147e-02, - 1.020429200603871836e-03, -1.026734257188876599e-03, - 5.678534821710372327e-02, 1.273635858276599142e-02, - -1.530143401888291177e-02, -1.061672032476311256e-01, - -2.486859787145567074e-02, 2.875323543588798395e-02}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -82,14 +47,19 @@ class TestInferDeepPotAFParamAParamPt : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/fparam_aparam.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("default", "expected_e"); + expected_f = ref.get("default", "expected_f"); + expected_v = ref.get("default", "expected_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_a_fparam_aparam_ptexpt.cc b/source/api_cc/tests/test_deeppot_a_fparam_aparam_ptexpt.cc index fe1ec116b8..8b07cbd90e 100644 --- a/source/api_cc/tests/test_deeppot_a_fparam_aparam_ptexpt.cc +++ b/source/api_cc/tests/test_deeppot_a_fparam_aparam_ptexpt.cc @@ -10,6 +10,7 @@ #include "DeepPot.h" #include "DeepPotPTExpt.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -17,6 +18,11 @@ #undef EPSILON #define EPSILON (std::is_same::value ? 1e-7 : 1e-4) +namespace { +constexpr const char* kRefPath = "../../tests/infer/fparam_aparam.expected"; +constexpr const char* kModelPath = "../../tests/infer/fparam_aparam.pt2"; +} // namespace + template class TestInferDeepPotAFParamAParamPtExpt : public ::testing::Test { protected: @@ -28,48 +34,9 @@ class TestInferDeepPotAFParamAParamPtExpt : public ::testing::Test { std::vector fparam = {0.25852028}; std::vector aparam = {0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028}; - std::vector expected_e = { - -1.038271223729636539e-01, -7.285433579124989123e-02, - -9.467600492266425860e-02, -1.467050207422957442e-01, - -7.660561676973243195e-02, -7.277296000253175023e-02}; - std::vector expected_f = { - 6.622266941151369601e-02, 5.278739714221529489e-02, - 2.265728009692277028e-02, -2.606048291367509331e-02, - -4.538812303131847109e-02, 1.058247419681241676e-02, - 1.679392617013223121e-01, -2.257826240741929533e-03, - -4.490146347357203138e-02, -1.148364179422036724e-01, - -1.169790528013799069e-02, 6.140403441496700837e-02, - -8.078778123309421355e-02, -5.838879041789352825e-02, - 6.773641084621376263e-02, -1.247724902386305318e-02, - 6.494524782787665373e-02, -1.174787360813439457e-01}; - std::vector expected_v = { - -1.589185601903579381e-01, 2.586167090689088510e-03, - -1.575150812458056548e-04, -1.855360549216640564e-02, - 1.949822308966445150e-02, -1.006552178977542650e-02, - 3.177030388421490936e-02, 1.714350280402104215e-03, - -1.290389705296313833e-03, -8.553511587973079699e-02, - -5.654638208496251539e-03, -1.286955066237439882e-02, - 2.464156699303176462e-02, -2.398203243424212178e-02, - -1.957110698882909630e-02, 2.233493653505165544e-02, - 6.107843889444162372e-03, 1.707076397717688723e-03, - -1.653994136896924094e-01, 3.894358809712639147e-02, - -2.169596032233910010e-02, 6.819702786556020371e-03, - -5.018240707559744503e-03, 2.640663592968431426e-03, - -1.985295554050418160e-03, -3.638422207618969423e-02, - 2.342932709960221863e-02, -8.501331666888653493e-02, - -2.181253119706856591e-03, 4.311299629418858387e-03, - -1.910329576491436726e-03, -1.808810428459609043e-03, - -1.540075460017477360e-03, -1.173703527688202929e-02, - -2.596307050960845741e-03, 6.705026635782097323e-03, - -9.038454847872562370e-02, 3.011717694088476838e-02, - -5.083053967307901710e-02, -2.951212926932282599e-03, - 2.342446057919112673e-02, -4.091208178777860222e-02, - -1.648470670751139844e-02, -2.872262362355524484e-02, - 4.763925761561256522e-02, -8.300037376164930147e-02, - 1.020429200603871836e-03, -1.026734257188876599e-03, - 5.678534821710372327e-02, 1.273635858276599142e-02, - -1.530143401888291177e-02, -1.061672032476311256e-01, - -2.486859787145567074e-02, 2.875323543588798395e-02}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -78,7 +45,7 @@ class TestInferDeepPotAFParamAParamPtExpt : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/fparam_aparam.pt2"); + dp.init(kModelPath); #endif } @@ -86,13 +53,17 @@ class TestInferDeepPotAFParamAParamPtExpt : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("default", "expected_e"); + expected_f = ref.get("default", "expected_f"); + expected_v = ref.get("default", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_default_fparam_pt.cc b/source/api_cc/tests/test_deeppot_default_fparam_pt.cc index 66f9e16359..fb83151ef5 100644 --- a/source/api_cc/tests/test_deeppot_default_fparam_pt.cc +++ b/source/api_cc/tests/test_deeppot_default_fparam_pt.cc @@ -10,6 +10,7 @@ #include #include "DeepPot.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -17,6 +18,13 @@ #undef EPSILON #define EPSILON (std::is_same::value ? 1e-7 : 1e-4) +namespace { +constexpr const char* kRefPath = + "../../tests/infer/fparam_aparam_default.expected"; +constexpr const char* kModelPath = + "../../tests/infer/fparam_aparam_default.pth"; +} // namespace + template class TestInferDeepPotDefaultFParamPt : public ::testing::Test { protected: @@ -30,36 +38,9 @@ class TestInferDeepPotDefaultFParamPt : public ::testing::Test { 0.25852028, 0.25852028, 0.25852028}; // explicit fparam for backward compat test std::vector fparam = {0.25852028}; - // expected values computed with default fparam - std::vector expected_e = { - -1.038271223729637e-01, -7.285433579124989e-02, -9.467600492266426e-02, - -1.467050207422953e-01, -7.660561676973243e-02, -7.277296000253175e-02}; - std::vector expected_f = { - 6.622266941151356e-02, 5.278739714221517e-02, 2.265728009692279e-02, - -2.606048291367521e-02, -4.538812303131843e-02, 1.058247419681242e-02, - 1.679392617013225e-01, -2.257826240741907e-03, -4.490146347357200e-02, - -1.148364179422036e-01, -1.169790528013792e-02, 6.140403441496690e-02, - -8.078778123309406e-02, -5.838879041789346e-02, 6.773641084621368e-02, - -1.247724902386317e-02, 6.494524782787654e-02, -1.174787360813438e-01}; - std::vector expected_v = { - -1.589185601903571e-01, 2.586167090689234e-03, -1.575150812459097e-04, - -1.855360549216658e-02, 1.949822308966458e-02, -1.006552178977554e-02, - 3.177030388421500e-02, 1.714350280402170e-03, -1.290389705296196e-03, - -8.553511587973063e-02, -5.654638208496338e-03, -1.286955066237458e-02, - 2.464156699303163e-02, -2.398203243424216e-02, -1.957110698882903e-02, - 2.233493653505151e-02, 6.107843889444162e-03, 1.707076397717704e-03, - -1.653994136896924e-01, 3.894358809712642e-02, -2.169596032233905e-02, - 6.819702786555932e-03, -5.018240707559808e-03, 2.640663592968395e-03, - -1.985295554050314e-03, -3.638422207618973e-02, 2.342932709960212e-02, - -8.501331666888623e-02, -2.181253119706635e-03, 4.311299629419011e-03, - -1.910329576491371e-03, -1.808810428459616e-03, -1.540075460017380e-03, - -1.173703527688186e-02, -2.596307050960764e-03, 6.705026635782070e-03, - -9.038454847872568e-02, 3.011717694088482e-02, -5.083053967307887e-02, - -2.951212926932095e-03, 2.342446057919113e-02, -4.091208178777853e-02, - -1.648470670751170e-02, -2.872262362355538e-02, 4.763925761561248e-02, - -8.300037376165001e-02, 1.020429200603740e-03, -1.026734257188870e-03, - 5.678534821710347e-02, 1.273635858276582e-02, -1.530143401888294e-02, - -1.061672032476309e-01, -2.486859787145545e-02, 2.875323543588796e-02}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -70,14 +51,19 @@ class TestInferDeepPotDefaultFParamPt : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/fparam_aparam_default.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("default", "expected_e"); + expected_f = ref.get("default", "expected_f"); + expected_v = ref.get("default", "expected_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_default_fparam_ptexpt.cc b/source/api_cc/tests/test_deeppot_default_fparam_ptexpt.cc index 996dcb1b50..72ac55c2c3 100644 --- a/source/api_cc/tests/test_deeppot_default_fparam_ptexpt.cc +++ b/source/api_cc/tests/test_deeppot_default_fparam_ptexpt.cc @@ -11,6 +11,7 @@ #include "DeepPot.h" #include "DeepPotPTExpt.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -18,6 +19,13 @@ #undef EPSILON #define EPSILON (std::is_same::value ? 1e-7 : 1e-4) +namespace { +constexpr const char* kRefPath = + "../../tests/infer/fparam_aparam_default.expected"; +constexpr const char* kModelPath = + "../../tests/infer/fparam_aparam_default.pt2"; +} // namespace + template class TestInferDeepPotDefaultFParamPtExpt : public ::testing::Test { protected: @@ -31,50 +39,9 @@ class TestInferDeepPotDefaultFParamPtExpt : public ::testing::Test { 0.25852028, 0.25852028, 0.25852028}; // explicit fparam for backward compat test std::vector fparam = {0.25852028}; - // expected values computed with default fparam - // (from pre-committed fparam_aparam_default.pth via gen_fparam_aparam.py) - std::vector expected_e = { - -1.038271223729636539e-01, -7.285433579124989123e-02, - -9.467600492266425860e-02, -1.467050207422957442e-01, - -7.660561676973243195e-02, -7.277296000253175023e-02}; - std::vector expected_f = { - 6.622266941151369601e-02, 5.278739714221529489e-02, - 2.265728009692277028e-02, -2.606048291367509331e-02, - -4.538812303131847109e-02, 1.058247419681241676e-02, - 1.679392617013223121e-01, -2.257826240741929533e-03, - -4.490146347357203138e-02, -1.148364179422036724e-01, - -1.169790528013799069e-02, 6.140403441496700837e-02, - -8.078778123309421355e-02, -5.838879041789352825e-02, - 6.773641084621376263e-02, -1.247724902386305318e-02, - 6.494524782787665373e-02, -1.174787360813439457e-01}; - std::vector expected_v = { - -1.589185601903579381e-01, 2.586167090689088510e-03, - -1.575150812458056548e-04, -1.855360549216640564e-02, - 1.949822308966445150e-02, -1.006552178977542650e-02, - 3.177030388421490936e-02, 1.714350280402104215e-03, - -1.290389705296313833e-03, -8.553511587973079699e-02, - -5.654638208496251539e-03, -1.286955066237439882e-02, - 2.464156699303176462e-02, -2.398203243424212178e-02, - -1.957110698882909630e-02, 2.233493653505165544e-02, - 6.107843889444162372e-03, 1.707076397717688723e-03, - -1.653994136896924094e-01, 3.894358809712639147e-02, - -2.169596032233910010e-02, 6.819702786556020371e-03, - -5.018240707559744503e-03, 2.640663592968431426e-03, - -1.985295554050418160e-03, -3.638422207618969423e-02, - 2.342932709960221863e-02, -8.501331666888653493e-02, - -2.181253119706856591e-03, 4.311299629418858387e-03, - -1.910329576491436726e-03, -1.808810428459609043e-03, - -1.540075460017477360e-03, -1.173703527688202929e-02, - -2.596307050960845741e-03, 6.705026635782097323e-03, - -9.038454847872562370e-02, 3.011717694088476838e-02, - -5.083053967307901710e-02, -2.951212926932282599e-03, - 2.342446057919112673e-02, -4.091208178777860222e-02, - -1.648470670751139844e-02, -2.872262362355524484e-02, - 4.763925761561256522e-02, -8.300037376164930147e-02, - 1.020429200603871836e-03, -1.026734257188876599e-03, - 5.678534821710372327e-02, 1.273635858276599142e-02, - -1.530143401888291177e-02, -1.061672032476311256e-01, - -2.486859787145567074e-02, 2.875323543588798395e-02}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -83,7 +50,7 @@ class TestInferDeepPotDefaultFParamPtExpt : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/fparam_aparam_default.pt2"); + dp.init(kModelPath); #endif } @@ -91,13 +58,17 @@ class TestInferDeepPotDefaultFParamPtExpt : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("default", "expected_e"); + expected_f = ref.get("default", "expected_f"); + expected_v = ref.get("default", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_dpa1_pt.cc b/source/api_cc/tests/test_deeppot_dpa1_pt.cc index 324537b87e..6fd24451e0 100644 --- a/source/api_cc/tests/test_deeppot_dpa1_pt.cc +++ b/source/api_cc/tests/test_deeppot_dpa1_pt.cc @@ -10,12 +10,20 @@ #include #include "DeepPot.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" #undef EPSILON #define EPSILON (std::is_same::value ? 1e-10 : 1e-4) +namespace { +// Reference values come from source/tests/infer/deeppot_dpa1.expected, which +// gen_dpa1.py regenerates at CI time alongside the .pth/.pt2 model files. +constexpr const char* kRefPath = "../../tests/infer/deeppot_dpa1.expected"; +constexpr const char* kModelPath = "../../tests/infer/deeppot_dpa1.pth"; +} // namespace + template class TestInferDeepPotDpa1Pt : public ::testing::Test { protected: @@ -24,50 +32,9 @@ class TestInferDeepPotDpa1Pt : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; - // Generated by source/tests/infer/gen_dpa1.py (PBC) - // Same weights as deeppot_dpa1.pt2 - std::vector expected_e = { - 5.386638169248214592e-02, 1.059305581653169626e-01, - 1.056662428333008108e-01, 5.332579202194744072e-02, - 1.055440262465702078e-01, 1.057385624627426024e-01}; - std::vector expected_f = { - 1.648023333711822261e-03, -1.810048390860390793e-03, - -5.640562778586664765e-04, 3.013935312554897467e-03, - 2.211467677140969111e-03, -2.373856990519772683e-03, - -2.310432060523760333e-03, -5.200587083006632388e-04, - 2.984950804954828157e-03, -2.118412923109444426e-03, - -1.589600452323191747e-04, -5.031858091203992222e-05, - 2.128234223750871245e-03, 2.940938628730816254e-03, - -4.128223543526785520e-03, -2.361347886384386214e-03, - -2.663339161478411616e-03, 4.131504587862436066e-03}; - std::vector expected_v = { - -5.780431274806642440e-04, -6.731158836777899682e-04, - 8.928830465533880122e-05, -4.786034663686604580e-04, - 8.892019221515710860e-04, 2.219211131658886931e-04, - -4.434673793050388494e-05, 1.863130189461770551e-04, - -3.790236017741206937e-05, -3.369804496903394848e-03, - 7.855880134671675268e-04, 1.743143964676567093e-03, - -1.426107460769170674e-03, 1.064489517343411660e-04, - 1.175541688057654688e-03, 1.938223402174633642e-03, - -6.492213546077969669e-04, -1.365956216959145295e-03, - -2.861954432782880600e-03, -1.773174860048345016e-03, - 1.277805252537157332e-03, 2.791729211298507834e-04, - -6.792377647208073643e-04, 1.097327565792464358e-04, - 9.259305614577704058e-04, 1.990815741066720955e-03, - -1.427531754436174886e-03, -6.007921168277090230e-04, - -4.342612523625760624e-04, 9.518674371962711689e-04, - -4.117735433350122251e-04, -1.422578249509541906e-04, - 1.669790464078422653e-04, 7.799013571504639876e-04, - 1.602754100511418107e-04, -1.667144996316817203e-04, - -2.790099105181320996e-03, -1.030047613180968972e-03, - 1.674076778664501837e-03, 6.636718025016051081e-04, - -1.175563308688121634e-03, 1.897194888911759789e-03, - -7.706408238661761889e-04, 1.660842536210703924e-03, - -2.685666208624810317e-03, -3.130480608254443929e-03, - -2.935998256729172636e-04, 2.485449126469695103e-04, - -2.044971674634045271e-03, -6.830748118353441615e-04, - 8.723614811463991899e-04, 3.155658891390614521e-03, - 1.094705622601841247e-03, -1.414833135157768764e-03}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -78,14 +45,19 @@ class TestInferDeepPotDpa1Pt : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/deeppot_dpa1.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("pbc", "expected_e"); + expected_f = ref.get("pbc", "expected_f"); + expected_v = ref.get("pbc", "expected_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } @@ -171,49 +143,9 @@ class TestInferDeepPotDpa1PtNoPbc : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {}; - // Generated by source/tests/infer/gen_dpa1.py (NoPbc) - std::vector expected_e = { - 5.641189028707595948e-02, 1.061963332622648665e-01, - 1.061816546452520604e-01, 5.345089797582680546e-02, - 1.056741039642918600e-01, 1.057524180734084607e-01}; - std::vector expected_f = { - -3.072930739880543310e-04, 1.287308823463468883e-04, - 2.325461100450139330e-04, 3.072930739880543310e-04, - -1.287308823463468883e-04, -2.325461100450139330e-04, - 8.145642124706340120e-04, -1.013443003399291530e-04, - 1.027376450650044392e-04, -1.525042369849348087e-03, - 9.724660386441295185e-06, -2.637088172652348470e-04, - 2.943676073439134653e-03, 2.725788047293053844e-03, - -3.882816498501044569e-03, -2.233197916060420361e-03, - -2.634168407339566257e-03, 4.043787670701274976e-03}; - std::vector expected_v = { - 7.690235058806288090e-04, -3.221584957067486670e-04, - -5.819637341799332227e-04, -3.221584957067492091e-04, - 1.349582887420156126e-04, 2.437956183726743475e-04, - -5.819637341799395111e-04, 2.437956183726751064e-04, - 4.404049880280591417e-04, -9.964203806317891397e-04, - 4.174193486430455681e-04, 7.540478556132436524e-04, - 4.174193486430458934e-04, -1.748648622693831176e-04, - -3.158849124866286288e-04, 7.540478556132498324e-04, - -3.158849124866294419e-04, -5.706308096532668791e-04, - -1.502820864633459211e-03, 2.276206872366074579e-04, - -2.355522888214717139e-04, 2.038607715354323201e-04, - -3.769132204670805602e-05, 3.903774408363665086e-05, - -2.601012918842465858e-04, 4.388984753508028396e-05, - -3.958932226991843692e-05, 2.399483162566252992e-04, - -4.383767135451629299e-04, 9.058040635350809132e-04, - -3.480376811900160578e-04, -1.023460282968784163e-04, - 1.069757548267320551e-04, 7.554026784872882325e-04, - 1.052835549305723749e-04, -8.105515243794243893e-05, - -5.835881428269892868e-04, -1.264750641879006793e-03, - 1.968091530552973020e-03, 3.905956580851997068e-04, - -1.141849627737433551e-03, 1.833849831634470733e-03, - -6.399943610726106791e-04, 1.624578487870950022e-03, - -2.620009641506095173e-03, -2.277492702178959827e-03, - -1.975376013403041739e-04, 1.395669241442570353e-04, - -1.919463017958483383e-03, -6.656963908160604126e-04, - 8.452260876957553085e-04, 2.922603203880410130e-03, - 1.051337527903990765e-03, -1.351073729135638529e-03}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -224,14 +156,19 @@ class TestInferDeepPotDpa1PtNoPbc : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/deeppot_dpa1.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("nopbc", "expected_e"); + expected_f = ref.get("nopbc", "expected_f"); + expected_v = ref.get("nopbc", "expected_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_dpa1_ptexpt.cc b/source/api_cc/tests/test_deeppot_dpa1_ptexpt.cc index c5d3b90303..d42f56b9d0 100644 --- a/source/api_cc/tests/test_deeppot_dpa1_ptexpt.cc +++ b/source/api_cc/tests/test_deeppot_dpa1_ptexpt.cc @@ -11,12 +11,18 @@ #include "DeepPot.h" #include "DeepPotPTExpt.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" #undef EPSILON #define EPSILON (std::is_same::value ? 1e-10 : 1e-4) +namespace { +constexpr const char* kRefPath = "../../tests/infer/deeppot_dpa1.expected"; +constexpr const char* kModelPath = "../../tests/infer/deeppot_dpa1.pt2"; +} // namespace + template class TestInferDeepPotDpa1PtExpt : public ::testing::Test { protected: @@ -25,50 +31,9 @@ class TestInferDeepPotDpa1PtExpt : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; - // Generated by source/tests/infer/gen_dpa1.py (PBC) - // Same weights as deeppot_dpa1.pt2 - std::vector expected_e = { - 5.386638169248214592e-02, 1.059305581653169626e-01, - 1.056662428333008108e-01, 5.332579202194744072e-02, - 1.055440262465702078e-01, 1.057385624627426024e-01}; - std::vector expected_f = { - 1.648023333711822261e-03, -1.810048390860390793e-03, - -5.640562778586664765e-04, 3.013935312554897467e-03, - 2.211467677140969111e-03, -2.373856990519772683e-03, - -2.310432060523760333e-03, -5.200587083006632388e-04, - 2.984950804954828157e-03, -2.118412923109444426e-03, - -1.589600452323191747e-04, -5.031858091203992222e-05, - 2.128234223750871245e-03, 2.940938628730816254e-03, - -4.128223543526785520e-03, -2.361347886384386214e-03, - -2.663339161478411616e-03, 4.131504587862436066e-03}; - std::vector expected_v = { - -5.780431274806642440e-04, -6.731158836777899682e-04, - 8.928830465533880122e-05, -4.786034663686604580e-04, - 8.892019221515710860e-04, 2.219211131658886931e-04, - -4.434673793050388494e-05, 1.863130189461770551e-04, - -3.790236017741206937e-05, -3.369804496903394848e-03, - 7.855880134671675268e-04, 1.743143964676567093e-03, - -1.426107460769170674e-03, 1.064489517343411660e-04, - 1.175541688057654688e-03, 1.938223402174633642e-03, - -6.492213546077969669e-04, -1.365956216959145295e-03, - -2.861954432782880600e-03, -1.773174860048345016e-03, - 1.277805252537157332e-03, 2.791729211298507834e-04, - -6.792377647208073643e-04, 1.097327565792464358e-04, - 9.259305614577704058e-04, 1.990815741066720955e-03, - -1.427531754436174886e-03, -6.007921168277090230e-04, - -4.342612523625760624e-04, 9.518674371962711689e-04, - -4.117735433350122251e-04, -1.422578249509541906e-04, - 1.669790464078422653e-04, 7.799013571504639876e-04, - 1.602754100511418107e-04, -1.667144996316817203e-04, - -2.790099105181320996e-03, -1.030047613180968972e-03, - 1.674076778664501837e-03, 6.636718025016051081e-04, - -1.175563308688121634e-03, 1.897194888911759789e-03, - -7.706408238661761889e-04, 1.660842536210703924e-03, - -2.685666208624810317e-03, -3.130480608254443929e-03, - -2.935998256729172636e-04, 2.485449126469695103e-04, - -2.044971674634045271e-03, -6.830748118353441615e-04, - 8.723614811463991899e-04, 3.155658891390614521e-03, - 1.094705622601841247e-03, -1.414833135157768764e-03}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -77,7 +42,7 @@ class TestInferDeepPotDpa1PtExpt : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/deeppot_dpa1.pt2"); + dp.init(kModelPath); #endif } @@ -85,13 +50,17 @@ class TestInferDeepPotDpa1PtExpt : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("pbc", "expected_e"); + expected_f = ref.get("pbc", "expected_f"); + expected_v = ref.get("pbc", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } @@ -182,49 +151,9 @@ class TestInferDeepPotDpa1PtExptNoPbc : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {}; - // Generated by source/tests/infer/gen_dpa1.py (NoPbc) - std::vector expected_e = { - 5.641189028707595948e-02, 1.061963332622648665e-01, - 1.061816546452520604e-01, 5.345089797582680546e-02, - 1.056741039642918600e-01, 1.057524180734084607e-01}; - std::vector expected_f = { - -3.072930739880543310e-04, 1.287308823463468883e-04, - 2.325461100450139330e-04, 3.072930739880543310e-04, - -1.287308823463468883e-04, -2.325461100450139330e-04, - 8.145642124706340120e-04, -1.013443003399291530e-04, - 1.027376450650044392e-04, -1.525042369849348087e-03, - 9.724660386441295185e-06, -2.637088172652348470e-04, - 2.943676073439134653e-03, 2.725788047293053844e-03, - -3.882816498501044569e-03, -2.233197916060420361e-03, - -2.634168407339566257e-03, 4.043787670701274976e-03}; - std::vector expected_v = { - 7.690235058806288090e-04, -3.221584957067486670e-04, - -5.819637341799332227e-04, -3.221584957067492091e-04, - 1.349582887420156126e-04, 2.437956183726743475e-04, - -5.819637341799395111e-04, 2.437956183726751064e-04, - 4.404049880280591417e-04, -9.964203806317891397e-04, - 4.174193486430455681e-04, 7.540478556132436524e-04, - 4.174193486430458934e-04, -1.748648622693831176e-04, - -3.158849124866286288e-04, 7.540478556132498324e-04, - -3.158849124866294419e-04, -5.706308096532668791e-04, - -1.502820864633459211e-03, 2.276206872366074579e-04, - -2.355522888214717139e-04, 2.038607715354323201e-04, - -3.769132204670805602e-05, 3.903774408363665086e-05, - -2.601012918842465858e-04, 4.388984753508028396e-05, - -3.958932226991843692e-05, 2.399483162566252992e-04, - -4.383767135451629299e-04, 9.058040635350809132e-04, - -3.480376811900160578e-04, -1.023460282968784163e-04, - 1.069757548267320551e-04, 7.554026784872882325e-04, - 1.052835549305723749e-04, -8.105515243794243893e-05, - -5.835881428269892868e-04, -1.264750641879006793e-03, - 1.968091530552973020e-03, 3.905956580851997068e-04, - -1.141849627737433551e-03, 1.833849831634470733e-03, - -6.399943610726106791e-04, 1.624578487870950022e-03, - -2.620009641506095173e-03, -2.277492702178959827e-03, - -1.975376013403041739e-04, 1.395669241442570353e-04, - -1.919463017958483383e-03, -6.656963908160604126e-04, - 8.452260876957553085e-04, 2.922603203880410130e-03, - 1.051337527903990765e-03, -1.351073729135638529e-03}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -233,7 +162,7 @@ class TestInferDeepPotDpa1PtExptNoPbc : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/deeppot_dpa1.pt2"); + dp.init(kModelPath); #endif } @@ -241,13 +170,17 @@ class TestInferDeepPotDpa1PtExptNoPbc : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("nopbc", "expected_e"); + expected_f = ref.get("nopbc", "expected_f"); + expected_v = ref.get("nopbc", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_dpa2_pt.cc b/source/api_cc/tests/test_deeppot_dpa2_pt.cc index 180bf8363c..65829c55c8 100644 --- a/source/api_cc/tests/test_deeppot_dpa2_pt.cc +++ b/source/api_cc/tests/test_deeppot_dpa2_pt.cc @@ -9,13 +9,20 @@ #include #include "DeepPot.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" -// DPA2 models need relaxed epsilon for float32 due to attention layers #undef EPSILON #define EPSILON (std::is_same::value ? 1e-10 : 1e-4) +namespace { +// Reference values come from source/tests/infer/deeppot_dpa2.expected, which +// gen_dpa2.py regenerates at CI time alongside the .pth/.pt2 model files. +constexpr const char* kRefPath = "../../tests/infer/deeppot_dpa2.expected"; +constexpr const char* kModelPath = "../../tests/infer/deeppot_dpa2.pth"; +} // namespace + template class TestInferDeepPotDpa2Pt : public ::testing::Test { protected: @@ -24,50 +31,9 @@ class TestInferDeepPotDpa2Pt : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; - // Generated by source/tests/infer/gen_dpa2.py (PBC) - // Same weights as deeppot_dpa2.pt2 - std::vector expected_e = { - 7.071627938744207142e-02, 8.956842892510968879e-02, - 8.960487851717680030e-02, 7.041307335741320284e-02, - 8.946246778628771934e-02, 8.950273290096630308e-02}; - std::vector expected_f = { - -5.274693721628801856e-04, 1.193250440811189066e-03, - 1.867294153282934117e-04, 2.490457803117060009e-03, - 2.083159497669665578e-04, -2.131291141610240462e-03, - -1.979320483395129171e-03, -1.407207733401788464e-03, - 1.949836307851203227e-03, 1.915769838158783156e-03, - -6.293858809443212809e-04, 1.198454068477057414e-03, - 1.072803472681185637e-03, 2.312144719396729171e-03, - -3.535229553224201668e-03, -2.972241258399019662e-03, - -1.677117495628775105e-03, 2.331500903177888620e-03}; - std::vector expected_v = { - 1.517438219904506140e-04, 3.153641070825828705e-05, - 9.592624160681313423e-04, 1.512258434675041886e-03, - -1.374312681808020995e-03, 2.336195918698237822e-04, - -3.333563799352665547e-04, 2.508037892144997054e-04, - -8.530908676130223665e-04, -1.648192206593849162e-03, - 1.139229474487762515e-04, 7.262981059689609326e-04, - -5.912655960190413024e-04, 3.191721961395713810e-04, - 4.032426542912010792e-04, 1.491502657559045861e-03, - -1.574217190862803577e-04, -6.875599765903525531e-04, - -1.172563372550058675e-03, -8.714771871140328773e-04, - 7.011614650317343159e-04, -1.644887030084397038e-03, - 5.266671463186511828e-05, 1.823841393156752145e-04, - 1.227078953241444483e-03, 7.256669776064127338e-04, - -6.274876719194932752e-04, -1.732702232782646701e-03, - -2.907896824664109634e-05, -1.531684598556129744e-04, - -5.765915598519781951e-05, -5.233315267730154338e-04, - 8.197518693585480057e-04, -1.145904850968312741e-04, - 8.228334341042128908e-04, -1.309755110431354069e-03, - 1.263283100941724408e-04, -6.499776597446308216e-04, - 1.041035279848752512e-03, -1.266370818144572821e-04, - -6.309984851702504565e-04, 9.829003029184085489e-04, - 2.172809307868736898e-04, 9.264667977179697270e-04, - -1.439968658957715671e-03, -8.850345766150289825e-04, - -4.995478668532852586e-04, 6.942600029958925258e-04, - -9.964318945735069471e-04, -3.475307206780771938e-04, - 4.421486462026064622e-04, 1.480933133502598115e-03, - 4.956979243994461166e-04, -6.243338853763658915e-04}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -78,14 +44,19 @@ class TestInferDeepPotDpa2Pt : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/deeppot_dpa2.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("pbc", "expected_e"); + expected_f = ref.get("pbc", "expected_f"); + expected_v = ref.get("pbc", "expected_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } @@ -171,49 +142,9 @@ class TestInferDeepPotDpa2PtNoPbc : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {}; - // Generated by source/tests/infer/gen_dpa2.py (NoPbc) - std::vector expected_e = { - 7.040088508308872672e-02, 8.982469559367040057e-02, - 8.577623946212942219e-02, 7.040934177879884515e-02, - 8.945548314285678426e-02, 8.949825740664299478e-02}; - std::vector expected_f = { - -1.861122162562435728e-03, 7.796592843166958754e-04, - 1.408416771668870304e-03, 1.861122162562435728e-03, - -7.796592843166958754e-04, -1.408416771668870304e-03, - 7.989858611689789158e-06, -8.882999958486996055e-07, - 6.245020643919394922e-07, 1.902754128669860347e-03, - -6.352329301743543221e-04, 1.207752494569338045e-03, - 1.070369236473196111e-03, 2.315002648400190776e-03, - -3.541311301960455016e-03, -2.981113223754746147e-03, - -1.678881418229987875e-03, 2.332934305326725324e-03}; - std::vector expected_v = { - -6.127996334459595573e-04, 2.567133599570932054e-04, - 4.637402631482920312e-04, 2.567133599570871338e-04, - -1.075420832252682243e-04, -1.942695696972585040e-04, - 4.637402631482885618e-04, -1.942695696972585040e-04, - -3.509385775176268943e-04, -7.644307668502429987e-04, - 3.202345104372618725e-04, 5.784881478866719245e-04, - 3.202345104372679441e-04, -1.341522949129076922e-04, - -2.423396295200912730e-04, 5.784881478866736593e-04, - -2.423396295200912730e-04, -4.377748146169404588e-04, - -3.513757860850363137e-05, 3.832988937821590170e-06, - -2.110944049426024960e-06, 3.720402587844924420e-06, - -4.467285354302484369e-07, 2.713133828440792358e-07, - -2.247594248243392140e-06, 3.038521155323589437e-07, - -2.043480298083789665e-07, -1.805285605745314374e-03, - -3.299108526406708403e-05, -1.433503553029593508e-04, - -5.634907459799816040e-05, -5.244497082627216575e-04, - 8.225112559487391447e-04, -1.066279487329045012e-04, - 8.250564344742740593e-04, -1.314627112018488739e-03, - 1.418428782329920687e-04, -6.489353301914278088e-04, - 1.040194879737597151e-03, -1.290554683731088420e-04, - -6.315169755139156751e-04, 9.836240801541270423e-04, - 2.191667463880570682e-04, 9.277526988634050842e-04, - -1.441866538661381973e-03, -8.785258023073679035e-04, - -4.996756538244960522e-04, 6.950977407477803779e-04, - -9.960849399589096972e-04, -3.475760534132951024e-04, - 4.422812763073963316e-04, 1.479540117726085499e-03, - 4.955749403398957212e-04, -6.242526914391316982e-04}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -224,14 +155,19 @@ class TestInferDeepPotDpa2PtNoPbc : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/deeppot_dpa2.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("nopbc", "expected_e"); + expected_f = ref.get("nopbc", "expected_f"); + expected_v = ref.get("nopbc", "expected_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_dpa2_ptexpt.cc b/source/api_cc/tests/test_deeppot_dpa2_ptexpt.cc index 67bb8f129f..5814f65f1b 100644 --- a/source/api_cc/tests/test_deeppot_dpa2_ptexpt.cc +++ b/source/api_cc/tests/test_deeppot_dpa2_ptexpt.cc @@ -10,6 +10,7 @@ #include "DeepPot.h" #include "DeepPotPTExpt.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -17,6 +18,11 @@ #undef EPSILON #define EPSILON (std::is_same::value ? 1e-10 : 1e-4) +namespace { +constexpr const char* kRefPath = "../../tests/infer/deeppot_dpa2.expected"; +constexpr const char* kModelPath = "../../tests/infer/deeppot_dpa2.pt2"; +} // namespace + template class TestInferDeepPotDpa2PtExpt : public ::testing::Test { protected: @@ -25,49 +31,9 @@ class TestInferDeepPotDpa2PtExpt : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; - // Generated by source/tests/infer/gen_dpa2.py (PBC) - std::vector expected_e = { - 7.071627938744207142e-02, 8.956842892510968879e-02, - 8.960487851717680030e-02, 7.041307335741320284e-02, - 8.946246778628771934e-02, 8.950273290096630308e-02}; - std::vector expected_f = { - -5.274693721628801856e-04, 1.193250440811189066e-03, - 1.867294153282934117e-04, 2.490457803117060009e-03, - 2.083159497669665578e-04, -2.131291141610240462e-03, - -1.979320483395129171e-03, -1.407207733401788464e-03, - 1.949836307851203227e-03, 1.915769838158783156e-03, - -6.293858809443212809e-04, 1.198454068477057414e-03, - 1.072803472681185637e-03, 2.312144719396729171e-03, - -3.535229553224201668e-03, -2.972241258399019662e-03, - -1.677117495628775105e-03, 2.331500903177888620e-03}; - std::vector expected_v = { - 1.517438219904506140e-04, 3.153641070825828705e-05, - 9.592624160681313423e-04, 1.512258434675041886e-03, - -1.374312681808020995e-03, 2.336195918698237822e-04, - -3.333563799352665547e-04, 2.508037892144997054e-04, - -8.530908676130223665e-04, -1.648192206593849162e-03, - 1.139229474487762515e-04, 7.262981059689609326e-04, - -5.912655960190413024e-04, 3.191721961395713810e-04, - 4.032426542912010792e-04, 1.491502657559045861e-03, - -1.574217190862803577e-04, -6.875599765903525531e-04, - -1.172563372550058675e-03, -8.714771871140328773e-04, - 7.011614650317343159e-04, -1.644887030084397038e-03, - 5.266671463186511828e-05, 1.823841393156752145e-04, - 1.227078953241444483e-03, 7.256669776064127338e-04, - -6.274876719194932752e-04, -1.732702232782646701e-03, - -2.907896824664109634e-05, -1.531684598556129744e-04, - -5.765915598519781951e-05, -5.233315267730154338e-04, - 8.197518693585480057e-04, -1.145904850968312741e-04, - 8.228334341042128908e-04, -1.309755110431354069e-03, - 1.263283100941724408e-04, -6.499776597446308216e-04, - 1.041035279848752512e-03, -1.266370818144572821e-04, - -6.309984851702504565e-04, 9.829003029184085489e-04, - 2.172809307868736898e-04, 9.264667977179697270e-04, - -1.439968658957715671e-03, -8.850345766150289825e-04, - -4.995478668532852586e-04, 6.942600029958925258e-04, - -9.964318945735069471e-04, -3.475307206780771938e-04, - 4.421486462026064622e-04, 1.480933133502598115e-03, - 4.956979243994461166e-04, -6.243338853763658915e-04}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -76,7 +42,7 @@ class TestInferDeepPotDpa2PtExpt : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/deeppot_dpa2.pt2"); + dp.init(kModelPath); #endif } @@ -84,13 +50,17 @@ class TestInferDeepPotDpa2PtExpt : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("pbc", "expected_e"); + expected_f = ref.get("pbc", "expected_f"); + expected_v = ref.get("pbc", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } @@ -456,49 +426,9 @@ class TestInferDeepPotDpa2PtExptNoPbc : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {}; - // Generated by source/tests/infer/gen_dpa2.py (NoPbc) - std::vector expected_e = { - 7.040088508308872672e-02, 8.982469559367040057e-02, - 8.577623946212942219e-02, 7.040934177879884515e-02, - 8.945548314285678426e-02, 8.949825740664299478e-02}; - std::vector expected_f = { - -1.861122162562435728e-03, 7.796592843166958754e-04, - 1.408416771668870304e-03, 1.861122162562435728e-03, - -7.796592843166958754e-04, -1.408416771668870304e-03, - 7.989858611689789158e-06, -8.882999958486996055e-07, - 6.245020643919394922e-07, 1.902754128669860347e-03, - -6.352329301743543221e-04, 1.207752494569338045e-03, - 1.070369236473196111e-03, 2.315002648400190776e-03, - -3.541311301960455016e-03, -2.981113223754746147e-03, - -1.678881418229987875e-03, 2.332934305326725324e-03}; - std::vector expected_v = { - -6.127996334459595573e-04, 2.567133599570932054e-04, - 4.637402631482920312e-04, 2.567133599570871338e-04, - -1.075420832252682243e-04, -1.942695696972585040e-04, - 4.637402631482885618e-04, -1.942695696972585040e-04, - -3.509385775176268943e-04, -7.644307668502429987e-04, - 3.202345104372618725e-04, 5.784881478866719245e-04, - 3.202345104372679441e-04, -1.341522949129076922e-04, - -2.423396295200912730e-04, 5.784881478866736593e-04, - -2.423396295200912730e-04, -4.377748146169404588e-04, - -3.513757860850363137e-05, 3.832988937821590170e-06, - -2.110944049426024960e-06, 3.720402587844924420e-06, - -4.467285354302484369e-07, 2.713133828440792358e-07, - -2.247594248243392140e-06, 3.038521155323589437e-07, - -2.043480298083789665e-07, -1.805285605745314374e-03, - -3.299108526406708403e-05, -1.433503553029593508e-04, - -5.634907459799816040e-05, -5.244497082627216575e-04, - 8.225112559487391447e-04, -1.066279487329045012e-04, - 8.250564344742740593e-04, -1.314627112018488739e-03, - 1.418428782329920687e-04, -6.489353301914278088e-04, - 1.040194879737597151e-03, -1.290554683731088420e-04, - -6.315169755139156751e-04, 9.836240801541270423e-04, - 2.191667463880570682e-04, 9.277526988634050842e-04, - -1.441866538661381973e-03, -8.785258023073679035e-04, - -4.996756538244960522e-04, 6.950977407477803779e-04, - -9.960849399589096972e-04, -3.475760534132951024e-04, - 4.422812763073963316e-04, 1.479540117726085499e-03, - 4.955749403398957212e-04, -6.242526914391316982e-04}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -507,7 +437,7 @@ class TestInferDeepPotDpa2PtExptNoPbc : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/deeppot_dpa2.pt2"); + dp.init(kModelPath); #endif } @@ -515,13 +445,17 @@ class TestInferDeepPotDpa2PtExptNoPbc : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("nopbc", "expected_e"); + expected_f = ref.get("nopbc", "expected_f"); + expected_v = ref.get("nopbc", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_dpa3_pt.cc b/source/api_cc/tests/test_deeppot_dpa3_pt.cc index 5b9c53f167..4457c5e1fb 100644 --- a/source/api_cc/tests/test_deeppot_dpa3_pt.cc +++ b/source/api_cc/tests/test_deeppot_dpa3_pt.cc @@ -9,13 +9,20 @@ #include #include "DeepPot.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" -// DPA3 models need relaxed epsilon #undef EPSILON #define EPSILON (std::is_same::value ? 1e-10 : 1e-4) +namespace { +// Reference values come from source/tests/infer/deeppot_dpa3.expected, which +// gen_dpa3.py regenerates at CI time alongside the .pth/.pt2 model files. +constexpr const char* kRefPath = "../../tests/infer/deeppot_dpa3.expected"; +constexpr const char* kModelPath = "../../tests/infer/deeppot_dpa3.pth"; +} // namespace + template class TestInferDeepPotDpa3Pt : public ::testing::Test { protected: @@ -24,50 +31,9 @@ class TestInferDeepPotDpa3Pt : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; - // Generated by source/tests/infer/gen_dpa3.py (PBC) - // Same weights as deeppot_dpa3.pt2 - std::vector expected_e = { - 2.733142942358297023e-01, 2.768815473296480922e-01, - 2.781664369968356865e-01, 2.697839344989072519e-01, - 2.741210600049306945e-01, 2.752870928812235496e-01}; - std::vector expected_f = { - -1.962618723134541832e-02, 4.287158582278347702e-02, - 7.640666386947853050e-03, 5.554130248696588501e-02, - -6.501206231527984977e-03, -4.524468847893595158e-02, - -3.851051736663693714e-02, -3.620789238677154381e-02, - 3.756162244251591564e-02, 6.729090678104879264e-02, - -2.430710555108604037e-02, 4.496058666120762021e-02, - 9.285825331084011924e-03, 5.623126339971108029e-02, - -8.776072674283137698e-02, -7.398133000111631330e-02, - -3.208664505310900028e-02, 4.284253973109593966e-02}; - std::vector expected_v = { - -2.519191242984861884e-02, -7.976296517418629550e-04, - 2.293255716383547221e-02, -1.129879902880513709e-04, - -2.480533869648754441e-02, 5.147545203263749480e-03, - 2.250634701911344987e-02, 5.288887046140826331e-03, - -2.010244267109611085e-02, -1.779331319768159489e-02, - 3.093850189397499839e-03, 1.469388965841003300e-02, - -3.857294749719837688e-03, 1.122172669801067097e-03, - 3.015485878866499582e-03, 1.588838841470147090e-02, - -2.814760933954751562e-03, -1.277216714527013713e-02, - -8.763367643346370306e-03, -1.305889135368112908e-02, - 1.181350951828694096e-02, -6.506014073233991855e-03, - -6.021216432246893902e-03, 6.406967309407277100e-03, - 1.054423249710041179e-02, 1.210616766999832172e-02, - -1.127472660426425549e-02, -3.873334330831591787e-02, - -3.620067664760272686e-03, 1.173198873109224322e-03, - -3.979800321914496279e-03, -1.483777776121806245e-02, - 2.311848485249741111e-02, 1.659292900032220339e-03, - 2.315104663227764842e-02, -3.645194750481960122e-02, - -1.668107738824501848e-04, -7.331929353596922626e-03, - 1.141573012886789966e-02, -1.498650485705460686e-03, - -1.339178008942835431e-02, 2.104129816063767672e-02, - 2.247013447171188061e-03, 2.035538814221872148e-02, - -3.195007182084359104e-02, -2.339460083073257798e-02, - -1.001949167693141039e-02, 1.320033846426920537e-02, - -1.577941189045228843e-02, -6.283307183655661120e-03, - 8.237968913765561507e-03, 2.238394952866012630e-02, - 8.881021761757389166e-03, -1.162377795308391741e-02}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -78,14 +44,19 @@ class TestInferDeepPotDpa3Pt : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/deeppot_dpa3.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("pbc", "expected_e"); + expected_f = ref.get("pbc", "expected_f"); + expected_v = ref.get("pbc", "expected_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } @@ -171,49 +142,9 @@ class TestInferDeepPotDpa3PtNoPbc : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {}; - // Generated by source/tests/infer/gen_dpa3.py (NoPbc) - std::vector expected_e = { - 2.748896667984845887e-01, 2.803947322373078754e-01, - 2.865499847997139971e-01, 2.695555136277474895e-01, - 2.739584531066059925e-01, 2.752217127378932537e-01}; - std::vector expected_f = { - -4.469562373941994571e-02, 1.872384237732456838e-02, - 3.382371526226372882e-02, 4.469562373941994571e-02, - -1.872384237732456838e-02, -3.382371526226372882e-02, - -8.962417443747255821e-04, 6.973117535150641388e-05, - 3.708588577163370883e-05, 6.643516471939500678e-02, - -2.418189932122343649e-02, 4.484243027251725439e-02, - 9.031619071676464522e-03, 5.637239343551967569e-02, - -8.796029317613156262e-02, -7.457054204669674724e-02, - -3.226022528964775371e-02, 4.308077701784267244e-02}; - std::vector expected_v = { - -1.634330450074628072e-02, 6.846519453015231793e-03, - 1.236790610867266604e-02, 6.846519453015259549e-03, - -2.868136527614494058e-03, -5.181149856335852399e-03, - 1.236790610867266604e-02, -5.181149856335859338e-03, - -9.359496514671244993e-03, -1.673145706642453767e-02, - 7.009123906204950405e-03, 1.266164318540249911e-02, - 7.009123906204922649e-03, -2.936254609356120371e-03, - -5.304201874965906727e-03, 1.266164318540247136e-02, - -5.304201874965899788e-03, -9.581784032196449807e-03, - 2.483905957089865488e-03, -1.710616363479115602e-04, - -5.347582359011894028e-05, -1.996686279554130779e-04, - 1.446275632786597548e-05, 2.638112328458543858e-06, - -1.197563523836930226e-04, 1.205600575305949503e-05, - -4.593499883389132697e-06, -4.089897480719173473e-02, - -3.495830205935246404e-03, 1.154978330068986980e-03, - -3.627142383941225900e-03, -1.488475129792680290e-02, - 2.311785022979555293e-02, 1.347848716528848856e-03, - 2.315545736893441509e-02, -3.642400982788428221e-02, - -1.119743233540158867e-03, -7.327254171127076110e-03, - 1.144439607350029517e-02, -1.403015516843159061e-03, - -1.349644754565121341e-02, 2.117430870829728473e-02, - 2.103115217604090148e-03, 2.047643373328661420e-02, - -3.212706064943796069e-02, -2.418232649309504101e-02, - -1.012366394018440752e-02, 1.334822742508814941e-02, - -1.588798342485496506e-02, -6.330672283764562924e-03, - 8.295385033255518736e-03, 2.256291842331806241e-02, - 8.946234975702738179e-03, -1.170798305154926999e-02}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -224,14 +155,19 @@ class TestInferDeepPotDpa3PtNoPbc : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/deeppot_dpa3.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("nopbc", "expected_e"); + expected_f = ref.get("nopbc", "expected_f"); + expected_v = ref.get("nopbc", "expected_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_dpa3_ptexpt.cc b/source/api_cc/tests/test_deeppot_dpa3_ptexpt.cc index a76a11e94f..66c9235613 100644 --- a/source/api_cc/tests/test_deeppot_dpa3_ptexpt.cc +++ b/source/api_cc/tests/test_deeppot_dpa3_ptexpt.cc @@ -10,6 +10,7 @@ #include "DeepPot.h" #include "DeepPotPTExpt.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -17,6 +18,11 @@ #undef EPSILON #define EPSILON (std::is_same::value ? 1e-10 : 1e-4) +namespace { +constexpr const char* kRefPath = "../../tests/infer/deeppot_dpa3.expected"; +constexpr const char* kModelPath = "../../tests/infer/deeppot_dpa3.pt2"; +} // namespace + template class TestInferDeepPotDpa3PtExpt : public ::testing::Test { protected: @@ -25,49 +31,9 @@ class TestInferDeepPotDpa3PtExpt : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; - // Generated by source/tests/infer/gen_dpa3.py (PBC) - std::vector expected_e = { - 2.733142942358297023e-01, 2.768815473296480922e-01, - 2.781664369968356865e-01, 2.697839344989072519e-01, - 2.741210600049306945e-01, 2.752870928812235496e-01}; - std::vector expected_f = { - -1.962618723134541832e-02, 4.287158582278347702e-02, - 7.640666386947853050e-03, 5.554130248696588501e-02, - -6.501206231527984977e-03, -4.524468847893595158e-02, - -3.851051736663693714e-02, -3.620789238677154381e-02, - 3.756162244251591564e-02, 6.729090678104879264e-02, - -2.430710555108604037e-02, 4.496058666120762021e-02, - 9.285825331084011924e-03, 5.623126339971108029e-02, - -8.776072674283137698e-02, -7.398133000111631330e-02, - -3.208664505310900028e-02, 4.284253973109593966e-02}; - std::vector expected_v = { - -2.519191242984861884e-02, -7.976296517418629550e-04, - 2.293255716383547221e-02, -1.129879902880513709e-04, - -2.480533869648754441e-02, 5.147545203263749480e-03, - 2.250634701911344987e-02, 5.288887046140826331e-03, - -2.010244267109611085e-02, -1.779331319768159489e-02, - 3.093850189397499839e-03, 1.469388965841003300e-02, - -3.857294749719837688e-03, 1.122172669801067097e-03, - 3.015485878866499582e-03, 1.588838841470147090e-02, - -2.814760933954751562e-03, -1.277216714527013713e-02, - -8.763367643346370306e-03, -1.305889135368112908e-02, - 1.181350951828694096e-02, -6.506014073233991855e-03, - -6.021216432246893902e-03, 6.406967309407277100e-03, - 1.054423249710041179e-02, 1.210616766999832172e-02, - -1.127472660426425549e-02, -3.873334330831591787e-02, - -3.620067664760272686e-03, 1.173198873109224322e-03, - -3.979800321914496279e-03, -1.483777776121806245e-02, - 2.311848485249741111e-02, 1.659292900032220339e-03, - 2.315104663227764842e-02, -3.645194750481960122e-02, - -1.668107738824501848e-04, -7.331929353596922626e-03, - 1.141573012886789966e-02, -1.498650485705460686e-03, - -1.339178008942835431e-02, 2.104129816063767672e-02, - 2.247013447171188061e-03, 2.035538814221872148e-02, - -3.195007182084359104e-02, -2.339460083073257798e-02, - -1.001949167693141039e-02, 1.320033846426920537e-02, - -1.577941189045228843e-02, -6.283307183655661120e-03, - 8.237968913765561507e-03, 2.238394952866012630e-02, - 8.881021761757389166e-03, -1.162377795308391741e-02}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -76,7 +42,7 @@ class TestInferDeepPotDpa3PtExpt : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/deeppot_dpa3.pt2"); + dp.init(kModelPath); #endif } @@ -84,13 +50,17 @@ class TestInferDeepPotDpa3PtExpt : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("pbc", "expected_e"); + expected_f = ref.get("pbc", "expected_f"); + expected_v = ref.get("pbc", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } @@ -456,49 +426,9 @@ class TestInferDeepPotDpa3PtExptNoPbc : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {}; - // Generated by source/tests/infer/gen_dpa3.py (NoPbc) - std::vector expected_e = { - 2.748896667984845887e-01, 2.803947322373078754e-01, - 2.865499847997139971e-01, 2.695555136277474895e-01, - 2.739584531066059925e-01, 2.752217127378932537e-01}; - std::vector expected_f = { - -4.469562373941994571e-02, 1.872384237732456838e-02, - 3.382371526226372882e-02, 4.469562373941994571e-02, - -1.872384237732456838e-02, -3.382371526226372882e-02, - -8.962417443747255821e-04, 6.973117535150641388e-05, - 3.708588577163370883e-05, 6.643516471939500678e-02, - -2.418189932122343649e-02, 4.484243027251725439e-02, - 9.031619071676464522e-03, 5.637239343551967569e-02, - -8.796029317613156262e-02, -7.457054204669674724e-02, - -3.226022528964775371e-02, 4.308077701784267244e-02}; - std::vector expected_v = { - -1.634330450074628072e-02, 6.846519453015231793e-03, - 1.236790610867266604e-02, 6.846519453015259549e-03, - -2.868136527614494058e-03, -5.181149856335852399e-03, - 1.236790610867266604e-02, -5.181149856335859338e-03, - -9.359496514671244993e-03, -1.673145706642453767e-02, - 7.009123906204950405e-03, 1.266164318540249911e-02, - 7.009123906204922649e-03, -2.936254609356120371e-03, - -5.304201874965906727e-03, 1.266164318540247136e-02, - -5.304201874965899788e-03, -9.581784032196449807e-03, - 2.483905957089865488e-03, -1.710616363479115602e-04, - -5.347582359011894028e-05, -1.996686279554130779e-04, - 1.446275632786597548e-05, 2.638112328458543858e-06, - -1.197563523836930226e-04, 1.205600575305949503e-05, - -4.593499883389132697e-06, -4.089897480719173473e-02, - -3.495830205935246404e-03, 1.154978330068986980e-03, - -3.627142383941225900e-03, -1.488475129792680290e-02, - 2.311785022979555293e-02, 1.347848716528848856e-03, - 2.315545736893441509e-02, -3.642400982788428221e-02, - -1.119743233540158867e-03, -7.327254171127076110e-03, - 1.144439607350029517e-02, -1.403015516843159061e-03, - -1.349644754565121341e-02, 2.117430870829728473e-02, - 2.103115217604090148e-03, 2.047643373328661420e-02, - -3.212706064943796069e-02, -2.418232649309504101e-02, - -1.012366394018440752e-02, 1.334822742508814941e-02, - -1.588798342485496506e-02, -6.330672283764562924e-03, - 8.295385033255518736e-03, 2.256291842331806241e-02, - 8.946234975702738179e-03, -1.170798305154926999e-02}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -507,7 +437,7 @@ class TestInferDeepPotDpa3PtExptNoPbc : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/deeppot_dpa3.pt2"); + dp.init(kModelPath); #endif } @@ -515,13 +445,17 @@ class TestInferDeepPotDpa3PtExptNoPbc : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("nopbc", "expected_e"); + expected_f = ref.get("nopbc", "expected_f"); + expected_v = ref.get("nopbc", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_dpa_pt_spin.cc b/source/api_cc/tests/test_deeppot_dpa_pt_spin.cc index 20318504a2..4432ddd02b 100644 --- a/source/api_cc/tests/test_deeppot_dpa_pt_spin.cc +++ b/source/api_cc/tests/test_deeppot_dpa_pt_spin.cc @@ -10,6 +10,7 @@ #include #include "DeepSpin.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -17,6 +18,11 @@ #undef EPSILON #define EPSILON (std::is_same::value ? 1e-6 : 1e-1) +namespace { +constexpr const char* kRefPath = "../../tests/infer/deeppot_dpa_spin.expected"; +constexpr const char* kModelPath = "../../tests/infer/deeppot_dpa_spin.pth"; +} // namespace + template class TestInferDeepSpinDpaPt : public ::testing::Test { protected: @@ -28,71 +34,11 @@ class TestInferDeepSpinDpaPt : public ::testing::Test { std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; - // Generated by the following Python code: - // import numpy as np - // from deepmd.infer import DeepPot - // coord = np.array([ - // 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, - // 00.25, 3.32, 1.68, 3.36, 3.00, 1.81, - // 3.51, 2.51, 2.60, 4.27, 3.22, 1.56 - // ]).reshape(1, -1) - // spin = np.array([ - // 0.13, 0.02, 0.03, 0., 0., 0., 0., 0., 0., - // 0.14, 0.10, 0.12, 0., 0., 0., 0., 0., 0. - // ]).reshape(1, -1) - // atype = np.array([0, 1, 1, 0, 1, 1]) - // box = np.array([13., 0., 0., 0., 13., 0., 0., 0., 13.]).reshape(1, -1) - // dp = DeepPot("deeppot_dpa_spin.pth") - // e, f, v, ae, av, fm, _ = dp.eval(coord, box, atype, atomic=True, spin=spin) - // np.set_printoptions(precision=16) - // print(f"{e.ravel()=} {f.ravel()=} {v.ravel()=} {fm.ravel()=} - // {ae.ravel()=}") - - std::vector expected_e = { - 7.020322773655288e-03, 1.099636038493644e-01, 1.093176595258250e-01, - 4.865300228001564e-02, 1.096547558413134e-01, 1.099754340356070e-01, - }; - std::vector expected_f = { - 2.980086586841411e-02, 2.670602118823960e-03, -6.205408022135627e-03, - -7.946653268248605e-03, 4.217792180550986e-03, 1.822080579891798e-03, - -3.416928812442276e-03, -6.992749479424899e-03, 4.728288289346775e-03, - 5.049869641953204e-03, 1.550913149717830e-02, 1.801899070929784e-02, - -1.411871008097311e-02, -8.283139367982638e-03, -7.058623315726573e-03, - -9.368443348703582e-03, -7.121636949145627e-03, -1.130532824067422e-02, - }; - std::vector expected_fm = { - -1.112646578617150e+00, -2.239176906831133e-01, -2.513101985142691e-01, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - -9.763058480695873e-02, 1.564710428447471e-02, -3.735332673990924e-02, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - }; - std::vector expected_tot_v = { - -7.128128841285764e-02, -8.315622874246201e-03, -4.731536549332887e-03, - -1.341290773830820e-02, -1.469079587670170e-03, 1.056456080782730e-03, - -1.192681253424153e-02, 4.978114518702803e-03, -3.966123865761229e-03, - }; - std::vector expected_atom_v = { - -3.619151252102697e-03, -1.915456807909512e-03, -1.193634026800710e-03, - -1.785172610866009e-03, 4.134184812978909e-03, -6.166519257514488e-05, - -2.157590794793008e-03, -2.693885020778555e-04, 1.587443946069703e-03, - 2.056276410594536e-03, -1.371452525359132e-03, -3.000322809812329e-03, - -2.204910668541369e-03, -2.235579614907452e-04, 1.766238823282138e-03, - 1.610936535839619e-04, -2.104451576692437e-04, -1.804779669204414e-06, - -3.221463421325033e-02, -7.637227088481205e-03, 5.718223298429893e-03, - -2.919861817651578e-04, -7.691370555547318e-03, 4.007185089114448e-03, - 4.811410568749122e-04, 4.415618310181523e-03, -2.774565137306631e-03, - -5.845767386476995e-03, -9.718890770743884e-04, 2.149933205072918e-03, - -1.901140917532940e-03, 7.116473330687919e-04, -1.348184104909009e-03, - 2.280135921727739e-03, -1.281729466483908e-03, 2.259352377835986e-03, - -1.358169386053482e-02, 6.217682155741852e-03, -1.084162229060967e-02, - 1.479497817858454e-04, 3.526517898332583e-03, -5.588222116376142e-03, - -3.264343884716279e-03, 4.301831360658648e-03, -7.109217034201159e-03, - -1.807631811108731e-02, -2.637279531163817e-03, 2.435886074387011e-03, - -7.377647141388572e-03, -1.926501115012390e-03, 2.281103582246440e-03, - -9.427248486918859e-03, -1.977772025906360e-03, 2.072666761510075e-03, - }; + std::vector expected_e; + std::vector expected_f; + std::vector expected_fm; + std::vector expected_tot_v; + std::vector expected_atom_v; int natoms; double expected_tot_e; @@ -103,7 +49,15 @@ class TestInferDeepSpinDpaPt : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/deeppot_dpa_spin.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("pbc", "expected_e"); + expected_f = ref.get("pbc", "expected_f"); + expected_fm = ref.get("pbc", "expected_fm"); + expected_tot_v = ref.get("pbc", "expected_tot_v"); + expected_atom_v = ref.get("pbc", "expected_atom_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); @@ -205,72 +159,11 @@ class TestInferDeepSpinDpaPtNopbc : public ::testing::Test { 0.14, 0.10, 0.12, 0., 0., 0., 0., 0., 0.}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {}; - // Generated by the following Python code: - // import numpy as np - // from deepmd.infer import DeepPot - // coord = np.array([ - // 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, - // 00.25, 3.32, 1.68, 3.36, 3.00, 1.81, - // 3.51, 2.51, 2.60, 4.27, 3.22, 1.56 - // ]).reshape(1, -1) - // spin = np.array([ - // 0.13, 0.02, 0.03, 0., 0., 0., 0., 0., 0., - // 0.14, 0.10, 0.12, 0., 0., 0., 0., 0., 0. - // ]).reshape(1, -1) - // atype = np.array([0, 1, 1, 0, 1, 1]) - // box = None - // dp = DeepPot("deeppot_dpa_spin.pth") - // e, f, v, ae, av, fm, _ = dp.eval(coord, box, atype, atomic=True, - // spin=spin) - // np.set_printoptions(precision=16) - // print(f"{e.ravel()=} {f.ravel()=} {v.ravel()=} {fm.ravel()=} - // {ae.ravel()=}") - - std::vector expected_e = { - 1.298915294144196e-02, 1.095576145701290e-01, 1.083914166945241e-01, - 4.932338375417146e-02, 1.099860785812512e-01, 1.100478936528533e-01, - }; - std::vector expected_f = { - 1.300765817095240e-02, -1.593967210478553e-03, -3.196759265340465e-03, - -1.300765817095220e-02, 1.593967210478477e-03, 3.196759265340509e-03, - 9.196695370628910e-03, -9.044559760114149e-04, 5.658266727670325e-04, - 1.012744085443978e-02, 1.680427054831429e-02, 1.807036969424208e-02, - -1.133453822298158e-02, -8.941333904804914e-03, -6.627672717506913e-03, - -7.989598002087154e-03, -6.958480667497971e-03, -1.200852364950221e-02, - }; - std::vector expected_fm = { - -9.651705644713781e-01, -1.704326891282164e-01, -2.605677204117113e-01, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - -9.168034653189444e-02, 1.736913887115685e-02, -3.908906640474424e-02, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - }; - std::vector expected_tot_v = { - -2.794677047149250e-02, 2.706780654409338e-03, -1.543674466954783e-02, - -6.040095143502448e-03, 3.055091789429398e-03, -4.313832703172029e-03, - -1.604723023732680e-02, 1.777744336229196e-03, -5.171028133240485e-04, - }; - std::vector expected_atom_v = { - 2.306155467987514e-03, -9.660921555042744e-04, -1.745198732526081e-03, - -9.476983959938838e-04, 3.970087875108642e-04, 7.171771645359225e-04, - -1.713485354054099e-03, 7.178114321056426e-04, 1.296691619287112e-03, - 7.319511578522508e-03, -3.066281877489238e-03, -5.539089843206328e-03, - -2.318373397601943e-04, 9.712104773733529e-05, 1.754444733319547e-04, - -6.521165022942005e-04, 2.731839401501884e-04, 4.934935693035620e-04, - -2.688582999243521e-02, 2.879540148031285e-03, -1.319893926076197e-03, - 2.654650285707574e-03, -3.069982439259916e-04, 1.657790217325663e-04, - -1.692335959139460e-03, 2.136332667243511e-04, -1.340912177342011e-04, - 4.337039816878673e-03, -4.892467685548227e-04, 1.504317649360216e-03, - -5.929947364721471e-04, 9.606430484810017e-04, -1.606901551850972e-03, - 1.319957388254711e-03, -1.503407517480697e-03, 2.524877227122832e-03, - -3.426950456916239e-03, 6.054673894090045e-03, -9.902054694804960e-03, - -4.978554214552650e-04, 3.694171795596980e-03, -5.898283613865629e-03, - -2.340485739136391e-03, 4.340998169957810e-03, -7.094248555283199e-03, - -1.159669688552975e-02, -1.705812586163657e-03, 1.565174877705520e-03, - -6.424359535528532e-03, -1.786854645970792e-03, 2.132951802944129e-03, - -1.096876407095736e-02, -2.264474955228100e-03, 2.396174543979845e-03, - }; + std::vector expected_e; + std::vector expected_f; + std::vector expected_fm; + std::vector expected_tot_v; + std::vector expected_atom_v; int natoms; double expected_tot_e; @@ -281,7 +174,15 @@ class TestInferDeepSpinDpaPtNopbc : public ::testing::Test { #ifndef BUILD_PYTORCH GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init("../../tests/infer/deeppot_dpa_spin.pth"); + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("nopbc", "expected_e"); + expected_f = ref.get("nopbc", "expected_f"); + expected_fm = ref.get("nopbc", "expected_fm"); + expected_tot_v = ref.get("nopbc", "expected_tot_v"); + expected_atom_v = ref.get("nopbc", "expected_atom_v"); + + dp.init(kModelPath); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); diff --git a/source/api_cc/tests/test_deeppot_dpa_ptexpt.cc b/source/api_cc/tests/test_deeppot_dpa_ptexpt.cc index faa51a7fde..4a1b0d45df 100644 --- a/source/api_cc/tests/test_deeppot_dpa_ptexpt.cc +++ b/source/api_cc/tests/test_deeppot_dpa_ptexpt.cc @@ -9,6 +9,7 @@ #include "DeepPot.h" #include "DeepPotPTExpt.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -16,6 +17,11 @@ #undef EPSILON #define EPSILON (std::is_same::value ? 1e-10 : 1e-4) +namespace { +constexpr const char* kRefPath = "../../tests/infer/deeppot_dpa1.expected"; +constexpr const char* kModelPath = "../../tests/infer/deeppot_dpa1.pt2"; +} // namespace + template class TestInferDeepPotDpaPtExpt : public ::testing::Test { protected: @@ -24,49 +30,9 @@ class TestInferDeepPotDpaPtExpt : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; - // Generated by source/tests/infer/gen_dpa1.py - std::vector expected_e = { - 5.386638169248214592e-02, 1.059305581653169626e-01, - 1.056662428333008108e-01, 5.332579202194744072e-02, - 1.055440262465702078e-01, 1.057385624627426024e-01}; - std::vector expected_f = { - 1.648023333711822261e-03, -1.810048390860390793e-03, - -5.640562778586664765e-04, 3.013935312554897467e-03, - 2.211467677140969111e-03, -2.373856990519772683e-03, - -2.310432060523760333e-03, -5.200587083006632388e-04, - 2.984950804954828157e-03, -2.118412923109444426e-03, - -1.589600452323191747e-04, -5.031858091203992222e-05, - 2.128234223750871245e-03, 2.940938628730816254e-03, - -4.128223543526785520e-03, -2.361347886384386214e-03, - -2.663339161478411616e-03, 4.131504587862436066e-03}; - std::vector expected_v = { - -5.780431274806642440e-04, -6.731158836777899682e-04, - 8.928830465533880122e-05, -4.786034663686604580e-04, - 8.892019221515710860e-04, 2.219211131658886931e-04, - -4.434673793050388494e-05, 1.863130189461770551e-04, - -3.790236017741206937e-05, -3.369804496903394848e-03, - 7.855880134671675268e-04, 1.743143964676567093e-03, - -1.426107460769170674e-03, 1.064489517343411660e-04, - 1.175541688057654688e-03, 1.938223402174633642e-03, - -6.492213546077969669e-04, -1.365956216959145295e-03, - -2.861954432782880600e-03, -1.773174860048345016e-03, - 1.277805252537157332e-03, 2.791729211298507834e-04, - -6.792377647208073643e-04, 1.097327565792464358e-04, - 9.259305614577704058e-04, 1.990815741066720955e-03, - -1.427531754436174886e-03, -6.007921168277090230e-04, - -4.342612523625760624e-04, 9.518674371962711689e-04, - -4.117735433350122251e-04, -1.422578249509541906e-04, - 1.669790464078422653e-04, 7.799013571504639876e-04, - 1.602754100511418107e-04, -1.667144996316817203e-04, - -2.790099105181320996e-03, -1.030047613180968972e-03, - 1.674076778664501837e-03, 6.636718025016051081e-04, - -1.175563308688121634e-03, 1.897194888911759789e-03, - -7.706408238661761889e-04, 1.660842536210703924e-03, - -2.685666208624810317e-03, -3.130480608254443929e-03, - -2.935998256729172636e-04, 2.485449126469695103e-04, - -2.044971674634045271e-03, -6.830748118353441615e-04, - 8.723614811463991899e-04, 3.155658891390614521e-03, - 1.094705622601841247e-03, -1.414833135157768764e-03}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -75,7 +41,7 @@ class TestInferDeepPotDpaPtExpt : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/deeppot_dpa1.pt2"); + dp.init(kModelPath); #endif } @@ -83,13 +49,17 @@ class TestInferDeepPotDpaPtExpt : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("pbc", "expected_e"); + expected_f = ref.get("pbc", "expected_f"); + expected_v = ref.get("pbc", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } @@ -446,49 +416,9 @@ class TestInferDeepPotDpaPtExptNoPbc : public ::testing::Test { 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; std::vector atype = {0, 1, 1, 0, 1, 1}; std::vector box = {}; - // Generated by source/tests/infer/gen_dpa1.py (NoPbc) - std::vector expected_e = { - 5.641189028707595948e-02, 1.061963332622648665e-01, - 1.061816546452520604e-01, 5.345089797582680546e-02, - 1.056741039642918600e-01, 1.057524180734084607e-01}; - std::vector expected_f = { - -3.072930739880543310e-04, 1.287308823463468883e-04, - 2.325461100450139330e-04, 3.072930739880543310e-04, - -1.287308823463468883e-04, -2.325461100450139330e-04, - 8.145642124706340120e-04, -1.013443003399291530e-04, - 1.027376450650044392e-04, -1.525042369849348087e-03, - 9.724660386441295185e-06, -2.637088172652348470e-04, - 2.943676073439134653e-03, 2.725788047293053844e-03, - -3.882816498501044569e-03, -2.233197916060420361e-03, - -2.634168407339566257e-03, 4.043787670701274976e-03}; - std::vector expected_v = { - 7.690235058806288090e-04, -3.221584957067486670e-04, - -5.819637341799332227e-04, -3.221584957067492091e-04, - 1.349582887420156126e-04, 2.437956183726743475e-04, - -5.819637341799395111e-04, 2.437956183726751064e-04, - 4.404049880280591417e-04, -9.964203806317891397e-04, - 4.174193486430455681e-04, 7.540478556132436524e-04, - 4.174193486430458934e-04, -1.748648622693831176e-04, - -3.158849124866286288e-04, 7.540478556132498324e-04, - -3.158849124866294419e-04, -5.706308096532668791e-04, - -1.502820864633459211e-03, 2.276206872366074579e-04, - -2.355522888214717139e-04, 2.038607715354323201e-04, - -3.769132204670805602e-05, 3.903774408363665086e-05, - -2.601012918842465858e-04, 4.388984753508028396e-05, - -3.958932226991843692e-05, 2.399483162566252992e-04, - -4.383767135451629299e-04, 9.058040635350809132e-04, - -3.480376811900160578e-04, -1.023460282968784163e-04, - 1.069757548267320551e-04, 7.554026784872882325e-04, - 1.052835549305723749e-04, -8.105515243794243893e-05, - -5.835881428269892868e-04, -1.264750641879006793e-03, - 1.968091530552973020e-03, 3.905956580851997068e-04, - -1.141849627737433551e-03, 1.833849831634470733e-03, - -6.399943610726106791e-04, 1.624578487870950022e-03, - -2.620009641506095173e-03, -2.277492702178959827e-03, - -1.975376013403041739e-04, 1.395669241442570353e-04, - -1.919463017958483383e-03, -6.656963908160604126e-04, - 8.452260876957553085e-04, 2.922603203880410130e-03, - 1.051337527903990765e-03, -1.351073729135638529e-03}; + std::vector expected_e; + std::vector expected_f; + std::vector expected_v; int natoms; double expected_tot_e; std::vector expected_tot_v; @@ -497,7 +427,7 @@ class TestInferDeepPotDpaPtExptNoPbc : public ::testing::Test { static void SetUpTestSuite() { #if defined(BUILD_PYTORCH) && BUILD_PT_EXPT - dp.init("../../tests/infer/deeppot_dpa1.pt2"); + dp.init(kModelPath); #endif } @@ -505,13 +435,17 @@ class TestInferDeepPotDpaPtExptNoPbc : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("nopbc", "expected_e"); + expected_f = ref.get("nopbc", "expected_f"); + expected_v = ref.get("nopbc", "expected_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); EXPECT_EQ(natoms * 9, expected_v.size()); expected_tot_e = 0.; - expected_tot_v.resize(9); - std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + expected_tot_v.assign(9, 0.); for (int ii = 0; ii < natoms; ++ii) { expected_tot_e += expected_e[ii]; } diff --git a/source/api_cc/tests/test_deeppot_dpa_ptexpt_spin.cc b/source/api_cc/tests/test_deeppot_dpa_ptexpt_spin.cc index 5f5ae7a6b6..7d9b04ddc0 100644 --- a/source/api_cc/tests/test_deeppot_dpa_ptexpt_spin.cc +++ b/source/api_cc/tests/test_deeppot_dpa_ptexpt_spin.cc @@ -9,6 +9,7 @@ #include "DeepSpin.h" #include "DeepSpinPTExpt.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -16,6 +17,11 @@ #undef EPSILON #define EPSILON (std::is_same::value ? 1e-10 : 1e-4) +namespace { +constexpr const char* kRefPath = "../../tests/infer/deeppot_dpa_spin.expected"; +constexpr const char* kModelPath = "../../tests/infer/deeppot_dpa_spin.pt2"; +} // namespace + // ============================================================================ // PBC test fixture // ============================================================================ @@ -46,64 +52,24 @@ class TestInferDeepSpinDpaPtExpt : public ::testing::Test { void SetUp() override { // The .pt2 spin model requires the BUILD_PT_EXPT guard from the header. // If AOTInductor headers are missing, skip. - std::string model_path = "../../tests/infer/deeppot_dpa_spin.pt2"; { - std::ifstream f(model_path); + std::ifstream f(kModelPath); if (!f.good()) { - GTEST_SKIP() << "Skipping: " << model_path << " not found."; + GTEST_SKIP() << "Skipping: " << kModelPath << " not found."; } } #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT_SPIN GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init(model_path); - - // PBC reference values from gen_spin.py - expected_e = { - 7.020322773655288e-03, 1.099636038493644e-01, 1.093176595258250e-01, - 4.865300228001564e-02, 1.096547558413134e-01, 1.099754340356070e-01, - }; - expected_f = { - 2.980086586841411e-02, 2.670602118823960e-03, -6.205408022135627e-03, - -7.946653268248605e-03, 4.217792180550986e-03, 1.822080579891798e-03, - -3.416928812442276e-03, -6.992749479424899e-03, 4.728288289346775e-03, - 5.049869641953204e-03, 1.550913149717830e-02, 1.801899070929784e-02, - -1.411871008097311e-02, -8.283139367982638e-03, -7.058623315726573e-03, - -9.368443348703582e-03, -7.121636949145627e-03, -1.130532824067422e-02, - }; - expected_fm = { - -1.112646578617150e+00, -2.239176906831133e-01, -2.513101985142691e-01, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - -9.763058480695873e-02, 1.564710428447471e-02, -3.735332673990924e-02, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - }; - expected_tot_v = { - -7.128128841285764e-02, -8.315622874246201e-03, -4.731536549332887e-03, - -1.341290773830820e-02, -1.469079587670170e-03, 1.056456080782730e-03, - -1.192681253424153e-02, 4.978114518702803e-03, -3.966123865761229e-03, - }; - expected_atom_v = { - -3.619151252102697e-03, -1.915456807909512e-03, -1.193634026800710e-03, - -1.785172610866009e-03, 4.134184812978909e-03, -6.166519257514488e-05, - -2.157590794793008e-03, -2.693885020778555e-04, 1.587443946069703e-03, - 2.056276410594536e-03, -1.371452525359132e-03, -3.000322809812329e-03, - -2.204910668541369e-03, -2.235579614907452e-04, 1.766238823282138e-03, - 1.610936535839619e-04, -2.104451576692437e-04, -1.804779669204414e-06, - -3.221463421325033e-02, -7.637227088481205e-03, 5.718223298429893e-03, - -2.919861817651578e-04, -7.691370555547318e-03, 4.007185089114448e-03, - 4.811410568749122e-04, 4.415618310181523e-03, -2.774565137306631e-03, - -5.845767386476995e-03, -9.718890770743884e-04, 2.149933205072918e-03, - -1.901140917532940e-03, 7.116473330687919e-04, -1.348184104909009e-03, - 2.280135921727739e-03, -1.281729466483908e-03, 2.259352377835986e-03, - -1.358169386053482e-02, 6.217682155741852e-03, -1.084162229060967e-02, - 1.479497817858454e-04, 3.526517898332583e-03, -5.588222116376142e-03, - -3.264343884716279e-03, 4.301831360658648e-03, -7.109217034201159e-03, - -1.807631811108731e-02, -2.637279531163817e-03, 2.435886074387011e-03, - -7.377647141388572e-03, -1.926501115012390e-03, 2.281103582246440e-03, - -9.427248486918859e-03, -1.977772025906360e-03, 2.072666761510075e-03, - }; + dp.init(kModelPath); + + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("pbc", "expected_e"); + expected_f = ref.get("pbc", "expected_f"); + expected_fm = ref.get("pbc", "expected_fm"); + expected_tot_v = ref.get("pbc", "expected_tot_v"); + expected_atom_v = ref.get("pbc", "expected_atom_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); @@ -232,64 +198,24 @@ class TestInferDeepSpinDpaPtExptNopbc : public ::testing::Test { deepmd::DeepSpin dp; void SetUp() override { - std::string model_path = "../../tests/infer/deeppot_dpa_spin.pt2"; { - std::ifstream f(model_path); + std::ifstream f(kModelPath); if (!f.good()) { - GTEST_SKIP() << "Skipping: " << model_path << " not found."; + GTEST_SKIP() << "Skipping: " << kModelPath << " not found."; } } #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT_SPIN GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif - dp.init(model_path); - - // NoPBC reference values from gen_spin.py - expected_e = { - 1.298915294144196e-02, 1.095576145701290e-01, 1.083914166945241e-01, - 4.932338375417146e-02, 1.099860785812512e-01, 1.100478936528533e-01, - }; - expected_f = { - 1.300765817095240e-02, -1.593967210478553e-03, -3.196759265340465e-03, - -1.300765817095220e-02, 1.593967210478477e-03, 3.196759265340509e-03, - 9.196695370628910e-03, -9.044559760114149e-04, 5.658266727670325e-04, - 1.012744085443978e-02, 1.680427054831429e-02, 1.807036969424208e-02, - -1.133453822298158e-02, -8.941333904804914e-03, -6.627672717506913e-03, - -7.989598002087154e-03, -6.958480667497971e-03, -1.200852364950221e-02, - }; - expected_fm = { - -9.651705644713781e-01, -1.704326891282164e-01, -2.605677204117113e-01, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - -9.168034653189444e-02, 1.736913887115685e-02, -3.908906640474424e-02, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - }; - expected_tot_v = { - -2.794677047149250e-02, 2.706780654409338e-03, -1.543674466954783e-02, - -6.040095143502448e-03, 3.055091789429398e-03, -4.313832703172029e-03, - -1.604723023732680e-02, 1.777744336229196e-03, -5.171028133240485e-04, - }; - expected_atom_v = { - 2.306155467987514e-03, -9.660921555042744e-04, -1.745198732526081e-03, - -9.476983959938838e-04, 3.970087875108642e-04, 7.171771645359225e-04, - -1.713485354054099e-03, 7.178114321056426e-04, 1.296691619287112e-03, - 7.319511578522508e-03, -3.066281877489238e-03, -5.539089843206328e-03, - -2.318373397601943e-04, 9.712104773733529e-05, 1.754444733319547e-04, - -6.521165022942005e-04, 2.731839401501884e-04, 4.934935693035620e-04, - -2.688582999243521e-02, 2.879540148031285e-03, -1.319893926076197e-03, - 2.654650285707574e-03, -3.069982439259916e-04, 1.657790217325663e-04, - -1.692335959139460e-03, 2.136332667243511e-04, -1.340912177342011e-04, - 4.337039816878673e-03, -4.892467685548227e-04, 1.504317649360216e-03, - -5.929947364721471e-04, 9.606430484810017e-04, -1.606901551850972e-03, - 1.319957388254711e-03, -1.503407517480697e-03, 2.524877227122832e-03, - -3.426950456916239e-03, 6.054673894090045e-03, -9.902054694804960e-03, - -4.978554214552650e-04, 3.694171795596980e-03, -5.898283613865629e-03, - -2.340485739136391e-03, 4.340998169957810e-03, -7.094248555283199e-03, - -1.159669688552975e-02, -1.705812586163657e-03, 1.565174877705520e-03, - -6.424359535528532e-03, -1.786854645970792e-03, 2.132951802944129e-03, - -1.096876407095736e-02, -2.264474955228100e-03, 2.396174543979845e-03, - }; + dp.init(kModelPath); + + deepmd_test::ExpectedRef ref; + ref.load(kRefPath); + expected_e = ref.get("nopbc", "expected_e"); + expected_f = ref.get("nopbc", "expected_f"); + expected_fm = ref.get("nopbc", "expected_fm"); + expected_tot_v = ref.get("nopbc", "expected_tot_v"); + expected_atom_v = ref.get("nopbc", "expected_atom_v"); natoms = expected_e.size(); EXPECT_EQ(natoms * 3, expected_f.size()); diff --git a/source/api_cc/tests/test_deeppot_model_devi_ptexpt.cc b/source/api_cc/tests/test_deeppot_model_devi_ptexpt.cc index 6da4185adf..30cc934ff3 100644 --- a/source/api_cc/tests/test_deeppot_model_devi_ptexpt.cc +++ b/source/api_cc/tests/test_deeppot_model_devi_ptexpt.cc @@ -10,6 +10,7 @@ #include "DeepPot.h" #include "DeepPotPTExpt.h" +#include "expected_ref.h" #include "neighbor_list.h" #include "test_utils.h" @@ -426,12 +427,11 @@ class TestInferDeepPotModeDeviPtExptPrecomputed : public ::testing::Test { std::vector aparam = {0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028}; int natoms; - std::vector expected_md_f = { - 3.443412186399823823e-04, 1.456244134905365292e-04, - 2.585092315848599867e-04}; // max min avg - std::vector expected_md_v = { - 1.735782978938303146e-04, 2.441022592033971239e-05, - 7.333090508662540210e-05}; // max min mystd + // Layout: (max, min, avg) for std_f; (max, min, mystd) for std_v. + // Loaded from model_devi.expected at SetUp (regenerated by + // gen_model_devi.py). + std::vector expected_md_f; + std::vector expected_md_v; static deepmd::DeepPot dp0; static deepmd::DeepPot dp1; @@ -451,6 +451,10 @@ class TestInferDeepPotModeDeviPtExptPrecomputed : public ::testing::Test { #if !defined(BUILD_PYTORCH) || !BUILD_PT_EXPT GTEST_SKIP() << "Skip because PyTorch support is not enabled."; #endif + deepmd_test::ExpectedRef ref; + ref.load("../../tests/infer/model_devi.expected"); + expected_md_f = ref.get("default", "expected_md_f"); + expected_md_v = ref.get("default", "expected_md_v"); natoms = coord.size() / 3; }; diff --git a/source/tests/infer/gen_common.py b/source/tests/infer/gen_common.py index 4b542e43f6..fea29fc63e 100644 --- a/source/tests/infer/gen_common.py +++ b/source/tests/infer/gen_common.py @@ -57,7 +57,12 @@ def load_custom_ops(): def print_cpp_values(label, ae, f, av): - """Print C++ reference arrays for energy, force, and virial.""" + """Print C++ reference arrays for energy, force, and virial. + + Debug helper. Production gen scripts should write sidecar reference files + via ``write_expected_ref`` instead; this is kept for ad-hoc inspection + when porting models or comparing pt/pt_expt outputs by hand. + """ print(f"\n// ---- {label} ----") # noqa: T201 atom_energy = ae[0, :, 0] print(" std::vector expected_e = {") # noqa: T201 @@ -82,7 +87,10 @@ def print_cpp_values(label, ae, f, av): def print_cpp_spin_values(label, ae, f, fm, tot_v, av): - """Print C++ reference arrays for spin models (energy, force, force_mag, virial).""" + """Print C++ reference arrays for spin models. + + Debug helper, see ``print_cpp_values``. + """ print(f"\n// ---- {label} ----") # noqa: T201 atom_energy = ae[0, :, 0] print(" std::vector expected_e = {") # noqa: T201 @@ -118,3 +126,49 @@ def print_cpp_spin_values(label, ae, f, fm, tot_v, av): comma = "," if ii < len(av_flat) - 1 else "" print(f" {v:.18e}{comma}") # noqa: T201 print(" };") # noqa: T201 + + +def write_expected_ref(path, sections, source_script=None): + """Write a plain-text sidecar reference file for C++ tests. + + Parameters + ---------- + path : str + Output file path. + sections : dict[str, dict[str, np.ndarray]] + Mapping ``case_name -> {array_name: 1-D or flattenable array}``. + source_script : str, optional + Name of the gen script for the header comment. + + Notes + ----- + File layout:: + + # auto-generated by -- do not edit + [pbc] + expected_e 6 + 5.386638169248214592e-02 + ... + expected_f 18 + ... + + [nopbc] + ... + """ + import numpy as np + + lines = [] + if source_script: + lines.append(f"# auto-generated by {source_script} -- do not edit") + else: + lines.append("# auto-generated -- do not edit") + for case_name, arrays in sections.items(): + lines.append(f"[{case_name}]") + for key, arr in arrays.items(): + flat = np.asarray(arr).reshape(-1) + lines.append(f"{key} {flat.size}") + for v in flat: + lines.append(f"{float(v):.18e}") + lines.append("") # blank line between sections + with open(path, "w") as fp: + fp.write("\n".join(lines).rstrip() + "\n") diff --git a/source/tests/infer/gen_dpa1.py b/source/tests/infer/gen_dpa1.py index d587d7e534..7eaaae4ae2 100644 --- a/source/tests/infer/gen_dpa1.py +++ b/source/tests/infer/gen_dpa1.py @@ -19,7 +19,7 @@ from gen_common import ( ensure_inductor_compiler, load_custom_ops, - print_cpp_values, + write_expected_ref, ) @@ -133,12 +133,30 @@ def main(): e1, f1, v1, ae1, av1 = dp.eval(coord, box, atype, atomic=True) print(f"\n// PBC total energy: {e1[0, 0]:.18e}") # noqa: T201 - print_cpp_values("PBC reference values", ae1, f1, av1) # ---- 5. Run inference for NoPbc test ---- e_np, f_np, v_np, ae_np, av_np = dp.eval(coord, None, atype, atomic=True) print(f"\n// NoPbc total energy: {e_np[0, 0]:.18e}") # noqa: T201 - print_cpp_values("NoPbc reference values", ae_np, f_np, av_np) + + # ---- 5b. Write sidecar reference file consumed by C++ tests ---- + ref_path = os.path.join(base_dir, "deeppot_dpa1.expected") + write_expected_ref( + ref_path, + sections={ + "pbc": { + "expected_e": ae1[0, :, 0], + "expected_f": f1[0], + "expected_v": av1[0], + }, + "nopbc": { + "expected_e": ae_np[0, :, 0], + "expected_f": f_np[0], + "expected_v": av_np[0], + }, + }, + source_script="source/tests/infer/gen_dpa1.py", + ) + print(f"Wrote {ref_path}") # noqa: T201 # ---- 6. Verify .pth gives same results ---- dp_pth = DeepPot(pth_path) diff --git a/source/tests/infer/gen_dpa2.py b/source/tests/infer/gen_dpa2.py index 8ce277fcf5..fba5341b02 100644 --- a/source/tests/infer/gen_dpa2.py +++ b/source/tests/infer/gen_dpa2.py @@ -19,7 +19,7 @@ from gen_common import ( ensure_inductor_compiler, load_custom_ops, - print_cpp_values, + write_expected_ref, ) @@ -156,12 +156,30 @@ def main(): e1, f1, v1, ae1, av1 = dp.eval(coord, box, atype, atomic=True) print(f"\n// PBC total energy: {e1[0, 0]:.18e}") # noqa: T201 - print_cpp_values("PBC reference values", ae1, f1, av1) # ---- 5. Run inference for NoPbc test ---- e_np, f_np, v_np, ae_np, av_np = dp.eval(coord, None, atype, atomic=True) print(f"\n// NoPbc total energy: {e_np[0, 0]:.18e}") # noqa: T201 - print_cpp_values("NoPbc reference values", ae_np, f_np, av_np) + + # ---- 5b. Write sidecar reference file consumed by C++ tests ---- + ref_path = os.path.join(base_dir, "deeppot_dpa2.expected") + write_expected_ref( + ref_path, + sections={ + "pbc": { + "expected_e": ae1[0, :, 0], + "expected_f": f1[0], + "expected_v": av1[0], + }, + "nopbc": { + "expected_e": ae_np[0, :, 0], + "expected_f": f_np[0], + "expected_v": av_np[0], + }, + }, + source_script="source/tests/infer/gen_dpa2.py", + ) + print(f"Wrote {ref_path}") # noqa: T201 # ---- 6. Verify .pth gives same results ---- if os.path.exists(pth_path): diff --git a/source/tests/infer/gen_dpa3.py b/source/tests/infer/gen_dpa3.py index e5e2d66579..bf0d0967ae 100644 --- a/source/tests/infer/gen_dpa3.py +++ b/source/tests/infer/gen_dpa3.py @@ -19,7 +19,7 @@ from gen_common import ( ensure_inductor_compiler, load_custom_ops, - print_cpp_values, + write_expected_ref, ) @@ -134,12 +134,30 @@ def main(): e1, f1, v1, ae1, av1 = dp.eval(coord, box, atype, atomic=True) print(f"\n// PBC total energy: {e1[0, 0]:.18e}") # noqa: T201 - print_cpp_values("PBC reference values", ae1, f1, av1) # ---- 5. Run inference for NoPbc test ---- e_np, f_np, v_np, ae_np, av_np = dp.eval(coord, None, atype, atomic=True) print(f"\n// NoPbc total energy: {e_np[0, 0]:.18e}") # noqa: T201 - print_cpp_values("NoPbc reference values", ae_np, f_np, av_np) + + # ---- 5b. Write sidecar reference file consumed by C++ tests ---- + ref_path = os.path.join(base_dir, "deeppot_dpa3.expected") + write_expected_ref( + ref_path, + sections={ + "pbc": { + "expected_e": ae1[0, :, 0], + "expected_f": f1[0], + "expected_v": av1[0], + }, + "nopbc": { + "expected_e": ae_np[0, :, 0], + "expected_f": f_np[0], + "expected_v": av_np[0], + }, + }, + source_script="source/tests/infer/gen_dpa3.py", + ) + print(f"Wrote {ref_path}") # noqa: T201 # ---- 6. Verify .pth gives same results ---- if os.path.exists(pth_path): diff --git a/source/tests/infer/gen_fparam_aparam.py b/source/tests/infer/gen_fparam_aparam.py index 13dbe4ffcf..79f165e147 100644 --- a/source/tests/infer/gen_fparam_aparam.py +++ b/source/tests/infer/gen_fparam_aparam.py @@ -23,6 +23,7 @@ from gen_common import ( ensure_inductor_compiler, load_custom_ops, + write_expected_ref, ) @@ -145,35 +146,27 @@ def main(): atomic=True, ) - atom_energy = ae[0, :, 0] - force = f[0] - atom_virial = av[0] - - # Print C++ format - print("\n// ---- Reference values for C++ test (shared by .pth and .pt2) ----") # noqa: T201 - print(f"// Total energy: {e[0, 0]:.18e}") # noqa: T201 - print() # noqa: T201 - print(" std::vector expected_e = {") # noqa: T201 - for ii, ev in enumerate(atom_energy): - comma = "," if ii < len(atom_energy) - 1 else "" - print(f" {ev:.18e}{comma}") # noqa: T201 - print(" };") # noqa: T201 - - print(" std::vector expected_f = {") # noqa: T201 - force_flat = force.flatten() - for ii, fv in enumerate(force_flat): - comma = "," if ii < len(force_flat) - 1 else "" - print(f" {fv:.18e}{comma}") # noqa: T201 - print(" };") # noqa: T201 - - print(" std::vector expected_v = {") # noqa: T201 - virial_flat = atom_virial.flatten() - for ii, vv in enumerate(virial_flat): - comma = "," if ii < len(virial_flat) - 1 else "" - print(f" {vv:.18e}{comma}") # noqa: T201 - print(" };") # noqa: T201 - - # ---- 4b. Reference values for default_fparam model (.pt2) ---- + # ---- 4a. Write sidecar for fparam_aparam.pt2/.pth tests ---- + # Consumers: test_deeppot_a_fparam_aparam_{pt,ptexpt,nframes_ptexpt}.cc + # Note: test_deeppot_ptexpt.cc also loads fparam_aparam.pt2 but only for + # JSON-metadata checks; it does not consume these reference values. + ref_path = os.path.join(base_dir, "fparam_aparam.expected") + write_expected_ref( + ref_path, + sections={ + "default": { + "expected_e": ae[0, :, 0], + "expected_f": f[0], + "expected_v": av[0], + }, + }, + source_script="source/tests/infer/gen_fparam_aparam.py", + ) + print(f"Wrote {ref_path}") # noqa: T201 + print(f"// fparam_aparam total energy: {e[0, 0]:.18e}") # noqa: T201 + + # ---- 4b. Sidecar for default_fparam model (.pt2) ---- + # Consumers: test_deeppot_default_fparam_{pt,ptexpt}.cc dp_default = DeepPot(pt2_default_path) e_d, f_d, _v_d, ae_d, av_d = dp_default.eval( coord, @@ -183,32 +176,20 @@ def main(): aparam=aparam_val, atomic=True, ) - atom_energy_d = ae_d[0, :, 0] - force_d = f_d[0] - atom_virial_d = av_d[0] - - print("\n// ---- Reference values for C++ default_fparam .pt2 test ----") # noqa: T201 - print(f"// Total energy: {e_d[0, 0]:.18e}") # noqa: T201 - print() # noqa: T201 - print(" std::vector expected_e = {") # noqa: T201 - for ii, ev in enumerate(atom_energy_d): - comma = "," if ii < len(atom_energy_d) - 1 else "" - print(f" {ev:.18e}{comma}") # noqa: T201 - print(" };") # noqa: T201 - - print(" std::vector expected_f = {") # noqa: T201 - force_flat_d = force_d.flatten() - for ii, fv in enumerate(force_flat_d): - comma = "," if ii < len(force_flat_d) - 1 else "" - print(f" {fv:.18e}{comma}") # noqa: T201 - print(" };") # noqa: T201 - - print(" std::vector expected_v = {") # noqa: T201 - virial_flat_d = atom_virial_d.flatten() - for ii, vv in enumerate(virial_flat_d): - comma = "," if ii < len(virial_flat_d) - 1 else "" - print(f" {vv:.18e}{comma}") # noqa: T201 - print(" };") # noqa: T201 + ref_path_default = os.path.join(base_dir, "fparam_aparam_default.expected") + write_expected_ref( + ref_path_default, + sections={ + "default": { + "expected_e": ae_d[0, :, 0], + "expected_f": f_d[0], + "expected_v": av_d[0], + }, + }, + source_script="source/tests/infer/gen_fparam_aparam.py", + ) + print(f"Wrote {ref_path_default}") # noqa: T201 + print(f"// default_fparam total energy: {e_d[0, 0]:.18e}") # noqa: T201 # ---- 5. Verify .pth gives same results ---- if pth_exported: diff --git a/source/tests/infer/gen_model_devi.py b/source/tests/infer/gen_model_devi.py index 7e43add02e..716c5a8ca3 100644 --- a/source/tests/infer/gen_model_devi.py +++ b/source/tests/infer/gen_model_devi.py @@ -19,6 +19,7 @@ from gen_common import ( ensure_inductor_compiler, load_custom_ops, + write_expected_ref, ) @@ -139,52 +140,10 @@ def main(): fparam_val = np.array([0.25852028], dtype=np.float64) aparam_val = np.array([0.25852028] * 6, dtype=np.float64) - # Inference with explicit fparam for both models - for idx, pt2_path in enumerate(models): - dp = DeepPot(pt2_path) - - # With explicit fparam + aparam - e, f, v, ae, av = dp.eval( - coord, - box, - atype, - fparam=fparam_val, - aparam=aparam_val, - atomic=True, - ) - - # Note: default_fparam path is tested at the C++ level; - # the Python pt2 runner filters None args so it can't be tested here. - - atom_energy = ae[0, :, 0] - force = f[0] - atom_virial = av[0] - - print(f"\n// ---- Model {idx} reference values (LAMMPS nlist path) ----") # noqa: T201 - print(f"// Total energy: {e[0, 0]:.18e}") # noqa: T201 - print() # noqa: T201 - print(f" // model {idx}") # noqa: T201 - print(" std::vector expected_e = {") # noqa: T201 - for ii, ev in enumerate(atom_energy): - comma = "," if ii < len(atom_energy) - 1 else "" - print(f" {ev:.18e}{comma}") # noqa: T201 - print(" };") # noqa: T201 - - print(" std::vector expected_f = {") # noqa: T201 - force_flat = force.flatten() - for ii, fv in enumerate(force_flat): - comma = "," if ii < len(force_flat) - 1 else "" - print(f" {fv:.18e}{comma}") # noqa: T201 - print(" };") # noqa: T201 - - print(" std::vector expected_v = {") # noqa: T201 - virial_flat = atom_virial.flatten() - for ii, vv in enumerate(virial_flat): - comma = "," if ii < len(virial_flat) - 1 else "" - print(f" {vv:.18e}{comma}") # noqa: T201 - print(" };") # noqa: T201 - # ---- 4. Compute deviation stats (LAMMPS nlist) ---- + # The C++ Precomputed test only consumes the model-deviation aggregate + # statistics (expected_md_f, expected_md_v); per-model atom_energy/force/ + # virial are not asserted on the C++ side, so we don't write them. dp0 = DeepPot(models[0]) dp1 = DeepPot(models[1]) @@ -241,14 +200,20 @@ def main(): print(f"// std_v: max={max_std_v:.18e} min={min_std_v:.18e} mystd={mystd_v:.18e}") # noqa: T201 - print("\n std::vector expected_md_f = {") # noqa: T201 - print(f" {max_std_f:.18e},") # noqa: T201 - print(f" {min_std_f:.18e},") # noqa: T201 - print(f" {avg_std_f:.18e}}}; // max min avg") # noqa: T201 - print(" std::vector expected_md_v = {") # noqa: T201 - print(f" {max_std_v:.18e},") # noqa: T201 - print(f" {min_std_v:.18e},") # noqa: T201 - print(f" {mystd_v:.18e}}}; // max min mystd") # noqa: T201 + # ---- 5. Write sidecar reference for C++ Precomputed test ---- + ref_path = os.path.join(base_dir, "model_devi.expected") + write_expected_ref( + ref_path, + sections={ + "default": { + # Layout: (max, min, avg) for std_f; (max, min, mystd) for std_v. + "expected_md_f": np.array([max_std_f, min_std_f, avg_std_f]), + "expected_md_v": np.array([max_std_v, min_std_v, mystd_v]), + }, + }, + source_script="source/tests/infer/gen_model_devi.py", + ) + print(f"Wrote {ref_path}") # noqa: T201 print("\nDone!") # noqa: T201 diff --git a/source/tests/infer/gen_spin.py b/source/tests/infer/gen_spin.py index d37e3207ff..c7c170b7d1 100644 --- a/source/tests/infer/gen_spin.py +++ b/source/tests/infer/gen_spin.py @@ -25,7 +25,7 @@ from gen_common import ( ensure_inductor_compiler, load_custom_ops, - print_cpp_spin_values, + write_expected_ref, ) @@ -174,14 +174,36 @@ def main(): e1, f1, v1, ae1, av1, fm1, _ = dp.eval(coord, box, atype, atomic=True, spin=spin) print(f"\n// PBC total energy: {e1[0, 0]:.18e}") # noqa: T201 - print_cpp_spin_values("PBC reference values", ae1, f1, fm1, v1, av1) # ---- 4. Run inference for NoPbc test ---- e_np, f_np, v_np, ae_np, av_np, fm_np, _ = dp.eval( coord, None, atype, atomic=True, spin=spin ) print(f"\n// NoPbc total energy: {e_np[0, 0]:.18e}") # noqa: T201 - print_cpp_spin_values("NoPbc reference values", ae_np, f_np, fm_np, v_np, av_np) + + # ---- 4b. Write sidecar reference file consumed by C++ tests ---- + ref_path = os.path.join(base_dir, "deeppot_dpa_spin.expected") + write_expected_ref( + ref_path, + sections={ + "pbc": { + "expected_e": ae1[0, :, 0], + "expected_f": f1[0], + "expected_fm": fm1[0], + "expected_tot_v": v1[0], + "expected_atom_v": av1[0], + }, + "nopbc": { + "expected_e": ae_np[0, :, 0], + "expected_f": f_np[0], + "expected_fm": fm_np[0], + "expected_tot_v": v_np[0], + "expected_atom_v": av_np[0], + }, + }, + source_script="source/tests/infer/gen_spin.py", + ) + print(f"Wrote {ref_path}") # noqa: T201 # ---- 5. Verify .pth gives same results ---- if os.path.exists(pth_path): diff --git a/source/tests/pt_expt/descriptor/test_dpa1.py b/source/tests/pt_expt/descriptor/test_dpa1.py index 24a1d36078..0fc971ba58 100644 --- a/source/tests/pt_expt/descriptor/test_dpa1.py +++ b/source/tests/pt_expt/descriptor/test_dpa1.py @@ -157,7 +157,11 @@ def test_compressed_forward(self, prec) -> None: dstd = 0.1 + np.abs(dstd) dtype = PRECISION_DICT[prec] - atol = 1e-5 if prec == "float32" else 1e-10 + # float32 tabulation error grows with embedding-net output magnitude; + # bias init N(0,1) (matching pt) widens the range vs. the earlier + # Glorot bias init, observed max-abs diff ~3.2e-5 — set 4e-5 with + # ~25% headroom over the measured value. + atol = 4e-5 if prec == "float32" else 1e-10 dd0 = DescrptDPA1( self.rcut, self.rcut_smth, diff --git a/source/tests/pt_expt/descriptor/test_se_atten_v2.py b/source/tests/pt_expt/descriptor/test_se_atten_v2.py index cc86c1600b..8f98e67510 100644 --- a/source/tests/pt_expt/descriptor/test_se_atten_v2.py +++ b/source/tests/pt_expt/descriptor/test_se_atten_v2.py @@ -145,7 +145,11 @@ def test_compressed_forward(self, prec) -> None: dstd = 0.1 + np.abs(dstd) dtype = PRECISION_DICT[prec] - atol = 1e-5 if prec == "float32" else 1e-10 + # float32 tabulation error grows with embedding-net output magnitude; + # bias init N(0,1) (matching pt) widens the range vs. the earlier + # Glorot bias init, observed max-abs diff ~3.2e-5 — set 4e-5 with + # ~25% headroom over the measured value. + atol = 4e-5 if prec == "float32" else 1e-10 dd0 = DescrptSeAttenV2( self.rcut, self.rcut_smth, From ba1249a8960e7dd93bd70c623477194371beb176 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 30 Apr 2026 22:07:39 +0800 Subject: [PATCH 3/7] test(lmp): replace hardcoded expected values in DPA3 LAMMPS tests with sidecar reads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI revealed test_lammps_dpa3_pt2.py and test_lammps_dpa3_pt2_nopbc.py still carried the old DPA3 hardcoded expected_ae/f/v arrays (originally copied from gen_dpa3.py output) that diverged once 35d5cb21 made the gen scripts emit new init values. - New `source/lmp/tests/expected_ref.py` mirrors the C++ `expected_ref.h` parser so LAMMPS Python tests load the same on-disk reference data produced by the gen scripts at CI time. - Refactor the two DPA3 LAMMPS tests to read deeppot_dpa3.expected. - Also refactor test_lammps_faparam_pt2.py to use fparam_aparam_default.expected for consistency (this test wasn't failing — gen_fparam_aparam.py loads weights from a committed .pth so init changes don't affect it — but the sidecar pattern is cleaner). - LAMMPS spin and model_devi tests are not refactored: they use a different atom config than the gen scripts (4 atoms vs 6) and their hardcoded refs are tolerant enough to survive the init shift in CI. --- source/lmp/tests/expected_ref.py | 35 ++++++ source/lmp/tests/test_lammps_dpa3_pt2.py | 104 ++---------------- .../lmp/tests/test_lammps_dpa3_pt2_nopbc.py | 104 ++---------------- source/lmp/tests/test_lammps_faparam_pt2.py | 49 +++------ 4 files changed, 74 insertions(+), 218 deletions(-) create mode 100644 source/lmp/tests/expected_ref.py diff --git a/source/lmp/tests/expected_ref.py b/source/lmp/tests/expected_ref.py new file mode 100644 index 0000000000..817c2fe588 --- /dev/null +++ b/source/lmp/tests/expected_ref.py @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +"""Reader for sidecar reference files written by `gen_common.write_expected_ref`. + +Mirrors the C++ loader in ``source/api_cc/tests/expected_ref.h`` so that +LAMMPS Python tests and the C++ unit tests both consume the same on-disk +reference data produced by ``source/tests/infer/gen_*.py``. +""" + +import numpy as np + + +def read_expected_ref(path): + """Parse a sidecar reference file into ``{section: {array_name: np.ndarray}}``.""" + sections = {} + current_section = None + with open(path) as fp: + lines = fp.readlines() + i = 0 + while i < len(lines): + line = lines[i].strip() + i += 1 + if not line or line.startswith("#"): + continue + if line.startswith("[") and line.endswith("]"): + current_section = line[1:-1] + sections[current_section] = {} + continue + if current_section is None: + raise ValueError(f"array '{line}' before any [section] in {path}") + key, count = line.split() + n = int(count) + values = [float(lines[i + j].strip()) for j in range(n)] + i += n + sections[current_section][key] = np.array(values, dtype=np.float64) + return sections diff --git a/source/lmp/tests/test_lammps_dpa3_pt2.py b/source/lmp/tests/test_lammps_dpa3_pt2.py index 7ce05f9a2d..2c712ea4aa 100644 --- a/source/lmp/tests/test_lammps_dpa3_pt2.py +++ b/source/lmp/tests/test_lammps_dpa3_pt2.py @@ -13,6 +13,9 @@ import constants import numpy as np import pytest +from expected_ref import ( + read_expected_ref, +) from lammps import ( PyLammps, ) @@ -21,103 +24,20 @@ ) pb_file = Path(__file__).parent.parent.parent / "tests" / "infer" / "deeppot_dpa3.pt2" +ref_file = ( + Path(__file__).parent.parent.parent / "tests" / "infer" / "deeppot_dpa3.expected" +) data_file = Path(__file__).parent / "data_dpa3_pt2.lmp" data_file_si = Path(__file__).parent / "data_dpa3_pt2.si" data_type_map_file = Path(__file__).parent / "data_type_map_dpa3_pt2.lmp" -# Reference values from gen_dpa3.py / test_deeppot_dpa3_ptexpt.cc (PBC) -expected_ae = np.array( - [ - 2.733142942358297023e-01, - 2.768815473296480922e-01, - 2.781664369968356865e-01, - 2.697839344989072519e-01, - 2.741210600049306945e-01, - 2.752870928812235496e-01, - ] -) +# Reference values written by source/tests/infer/gen_dpa3.py (PBC case). +_ref = read_expected_ref(ref_file)["pbc"] +expected_ae = _ref["expected_e"] expected_e = np.sum(expected_ae) -expected_f = np.array( - [ - -1.962618723134541832e-02, - 4.287158582278347702e-02, - 7.640666386947853050e-03, - 5.554130248696588501e-02, - -6.501206231527984977e-03, - -4.524468847893595158e-02, - -3.851051736663693714e-02, - -3.620789238677154381e-02, - 3.756162244251591564e-02, - 6.729090678104879264e-02, - -2.430710555108604037e-02, - 4.496058666120762021e-02, - 9.285825331084011924e-03, - 5.623126339971108029e-02, - -8.776072674283137698e-02, - -7.398133000111631330e-02, - -3.208664505310900028e-02, - 4.284253973109593966e-02, - ] -).reshape(6, 3) - -expected_v = -np.array( - [ - -2.519191242984861884e-02, - -7.976296517418629550e-04, - 2.293255716383547221e-02, - -1.129879902880513709e-04, - -2.480533869648754441e-02, - 5.147545203263749480e-03, - 2.250634701911344987e-02, - 5.288887046140826331e-03, - -2.010244267109611085e-02, - -1.779331319768159489e-02, - 3.093850189397499839e-03, - 1.469388965841003300e-02, - -3.857294749719837688e-03, - 1.122172669801067097e-03, - 3.015485878866499582e-03, - 1.588838841470147090e-02, - -2.814760933954751562e-03, - -1.277216714527013713e-02, - -8.763367643346370306e-03, - -1.305889135368112908e-02, - 1.181350951828694096e-02, - -6.506014073233991855e-03, - -6.021216432246893902e-03, - 6.406967309407277100e-03, - 1.054423249710041179e-02, - 1.210616766999832172e-02, - -1.127472660426425549e-02, - -3.873334330831591787e-02, - -3.620067664760272686e-03, - 1.173198873109224322e-03, - -3.979800321914496279e-03, - -1.483777776121806245e-02, - 2.311848485249741111e-02, - 1.659292900032220339e-03, - 2.315104663227764842e-02, - -3.645194750481960122e-02, - -1.668107738824501848e-04, - -7.331929353596922626e-03, - 1.141573012886789966e-02, - -1.498650485705460686e-03, - -1.339178008942835431e-02, - 2.104129816063767672e-02, - 2.247013447171188061e-03, - 2.035538814221872148e-02, - -3.195007182084359104e-02, - -2.339460083073257798e-02, - -1.001949167693141039e-02, - 1.320033846426920537e-02, - -1.577941189045228843e-02, - -6.283307183655661120e-03, - 8.237968913765561507e-03, - 2.238394952866012630e-02, - 8.881021761757389166e-03, - -1.162377795308391741e-02, - ] -).reshape(6, 9) +expected_f = _ref["expected_f"].reshape(6, 3) +# LAMMPS uses opposite sign convention for virial vs DeepPot atom_virial. +expected_v = -_ref["expected_v"].reshape(6, 9) box = np.array([0, 13, 0, 13, 0, 13, 0, 0, 0]) coord = np.array( diff --git a/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py b/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py index 95f208ff1b..940f2bdd92 100644 --- a/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py +++ b/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py @@ -13,6 +13,9 @@ import constants import numpy as np import pytest +from expected_ref import ( + read_expected_ref, +) from lammps import ( PyLammps, ) @@ -21,103 +24,20 @@ ) pb_file = Path(__file__).parent.parent.parent / "tests" / "infer" / "deeppot_dpa3.pt2" +ref_file = ( + Path(__file__).parent.parent.parent / "tests" / "infer" / "deeppot_dpa3.expected" +) data_file = Path(__file__).parent / "data_dpa3_pt2_nopbc.lmp" data_file_si = Path(__file__).parent / "data_dpa3_pt2_nopbc.si" data_type_map_file = Path(__file__).parent / "data_type_map_dpa3_pt2_nopbc.lmp" -# Reference values from gen_dpa3.py / test_deeppot_dpa3_ptexpt.cc (NoPbc) -expected_ae = np.array( - [ - 2.748896667984845887e-01, - 2.803947322373078754e-01, - 2.865499847997139971e-01, - 2.695555136277474895e-01, - 2.739584531066059925e-01, - 2.752217127378932537e-01, - ] -) +# Reference values written by source/tests/infer/gen_dpa3.py (NoPbc case). +_ref = read_expected_ref(ref_file)["nopbc"] +expected_ae = _ref["expected_e"] expected_e = np.sum(expected_ae) -expected_f = np.array( - [ - -4.469562373941994571e-02, - 1.872384237732456838e-02, - 3.382371526226372882e-02, - 4.469562373941994571e-02, - -1.872384237732456838e-02, - -3.382371526226372882e-02, - -8.962417443747255821e-04, - 6.973117535150641388e-05, - 3.708588577163370883e-05, - 6.643516471939500678e-02, - -2.418189932122343649e-02, - 4.484243027251725439e-02, - 9.031619071676464522e-03, - 5.637239343551967569e-02, - -8.796029317613156262e-02, - -7.457054204669674724e-02, - -3.226022528964775371e-02, - 4.308077701784267244e-02, - ] -).reshape(6, 3) - -expected_v = -np.array( - [ - -1.634330450074628072e-02, - 6.846519453015231793e-03, - 1.236790610867266604e-02, - 6.846519453015259549e-03, - -2.868136527614494058e-03, - -5.181149856335852399e-03, - 1.236790610867266604e-02, - -5.181149856335859338e-03, - -9.359496514671244993e-03, - -1.673145706642453767e-02, - 7.009123906204950405e-03, - 1.266164318540249911e-02, - 7.009123906204922649e-03, - -2.936254609356120371e-03, - -5.304201874965906727e-03, - 1.266164318540247136e-02, - -5.304201874965899788e-03, - -9.581784032196449807e-03, - 2.483905957089865488e-03, - -1.710616363479115602e-04, - -5.347582359011894028e-05, - -1.996686279554130779e-04, - 1.446275632786597548e-05, - 2.638112328458543858e-06, - -1.197563523836930226e-04, - 1.205600575305949503e-05, - -4.593499883389132697e-06, - -4.089897480719173473e-02, - -3.495830205935246404e-03, - 1.154978330068986980e-03, - -3.627142383941225900e-03, - -1.488475129792680290e-02, - 2.311785022979555293e-02, - 1.347848716528848856e-03, - 2.315545736893441509e-02, - -3.642400982788428221e-02, - -1.119743233540158867e-03, - -7.327254171127076110e-03, - 1.144439607350029517e-02, - -1.403015516843159061e-03, - -1.349644754565121341e-02, - 2.117430870829728473e-02, - 2.103115217604090148e-03, - 2.047643373328661420e-02, - -3.212706064943796069e-02, - -2.418232649309504101e-02, - -1.012366394018440752e-02, - 1.334822742508814941e-02, - -1.588798342485496506e-02, - -6.330672283764562924e-03, - 8.295385033255518736e-03, - 2.256291842331806241e-02, - 8.946234975702738179e-03, - -1.170798305154926999e-02, - ] -).reshape(6, 9) +expected_f = _ref["expected_f"].reshape(6, 3) +# LAMMPS uses opposite sign convention for virial vs DeepPot atom_virial. +expected_v = -_ref["expected_v"].reshape(6, 9) box = np.array([0, 13, 0, 13, 0, 13, 0, 0, 0]) coord = np.array( diff --git a/source/lmp/tests/test_lammps_faparam_pt2.py b/source/lmp/tests/test_lammps_faparam_pt2.py index b46c8c96fb..acfe032706 100644 --- a/source/lmp/tests/test_lammps_faparam_pt2.py +++ b/source/lmp/tests/test_lammps_faparam_pt2.py @@ -8,6 +8,9 @@ import numpy as np import pytest +from expected_ref import ( + read_expected_ref, +) from lammps import ( PyLammps, ) @@ -24,43 +27,21 @@ pt2_file_no_default = ( Path(__file__).parent.parent.parent / "tests" / "infer" / "fparam_aparam.pt2" ) +ref_file = ( + Path(__file__).parent.parent.parent + / "tests" + / "infer" + / "fparam_aparam_default.expected" +) data_file = Path(__file__).parent / "data.lmp" -# expected values from fparam_aparam_default.pt2 with default_fparam=[0.25852028] -# (identical to .pth — generated from the same dpmodel checkpoint via gen_fparam_aparam.py) -expected_ae = np.array( - [ - -1.038271223729637e-01, - -7.285433579124989e-02, - -9.467600492266426e-02, - -1.467050207422953e-01, - -7.660561676973243e-02, - -7.277296000253175e-02, - ] -) +# Reference values written by source/tests/infer/gen_fparam_aparam.py for the +# default-fparam case. The .pth and .pt2 produce identical values (verified by +# the gen script's parity check). +_ref = read_expected_ref(ref_file)["default"] +expected_ae = _ref["expected_e"] expected_e = np.sum(expected_ae) -expected_f = np.array( - [ - 6.622266941151356e-02, - 5.278739714221517e-02, - 2.265728009692279e-02, - -2.606048291367521e-02, - -4.538812303131843e-02, - 1.058247419681242e-02, - 1.679392617013225e-01, - -2.257826240741907e-03, - -4.490146347357200e-02, - -1.148364179422036e-01, - -1.169790528013792e-02, - 6.140403441496690e-02, - -8.078778123309406e-02, - -5.838879041789346e-02, - 6.773641084621368e-02, - -1.247724902386317e-02, - 6.494524782787654e-02, - -1.174787360813438e-01, - ] -).reshape(6, 3) +expected_f = _ref["expected_f"].reshape(6, 3) box = np.array([0, 13, 0, 13, 0, 13, 0, 0, 0]) coord = np.array( From 27d284b5bb6e2df010c3c30a9eed7410210c1fab Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 30 Apr 2026 22:46:20 +0800 Subject: [PATCH 4/7] test(lmp): guard sidecar load against missing file in non-PyTorch CI matrix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The paddle-only CI matrix (ENABLE_PYTORCH=0, ENABLE_PADDLE=1) doesn't run gen_*.py from test_cc_local.sh (those are gated on PyTorch), so deeppot_dpa3.expected and fparam_aparam_default.expected don't exist when LAMMPS tests collect. Module-level read_expected_ref() then raises FileNotFoundError at pytest collection time — before setup_module() can pytest.skip() based on ENABLE_PYTORCH. Wrap the module-level reads in try/except FileNotFoundError so the file loads cleanly when present and the test gets to its own ENABLE_PYTORCH guard otherwise. Generating .pt2 / .expected in paddle-only CI is not useful — .pt2 is the PyTorch AOTInductor format and paddle's LAMMPS plugin can't consume them; paddle has its own LAMMPS tests that load paddle-format models. --- source/lmp/tests/test_lammps_dpa3_pt2.py | 18 ++++++++++++------ source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py | 18 ++++++++++++------ source/lmp/tests/test_lammps_faparam_pt2.py | 14 ++++++++++---- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/source/lmp/tests/test_lammps_dpa3_pt2.py b/source/lmp/tests/test_lammps_dpa3_pt2.py index 2c712ea4aa..3f5e439790 100644 --- a/source/lmp/tests/test_lammps_dpa3_pt2.py +++ b/source/lmp/tests/test_lammps_dpa3_pt2.py @@ -32,12 +32,18 @@ data_type_map_file = Path(__file__).parent / "data_type_map_dpa3_pt2.lmp" # Reference values written by source/tests/infer/gen_dpa3.py (PBC case). -_ref = read_expected_ref(ref_file)["pbc"] -expected_ae = _ref["expected_e"] -expected_e = np.sum(expected_ae) -expected_f = _ref["expected_f"].reshape(6, 3) -# LAMMPS uses opposite sign convention for virial vs DeepPot atom_virial. -expected_v = -_ref["expected_v"].reshape(6, 9) +# Guarded with try/except because gen_dpa3.py only runs when PyTorch is built; +# matrices that disable PyTorch (e.g. paddle-only) skip the test in +# setup_module but still load this file at pytest collection time. +try: + _ref = read_expected_ref(ref_file)["pbc"] + expected_ae = _ref["expected_e"] + expected_e = np.sum(expected_ae) + expected_f = _ref["expected_f"].reshape(6, 3) + # LAMMPS uses opposite sign convention for virial vs DeepPot atom_virial. + expected_v = -_ref["expected_v"].reshape(6, 9) +except FileNotFoundError: + expected_ae = expected_e = expected_f = expected_v = None box = np.array([0, 13, 0, 13, 0, 13, 0, 0, 0]) coord = np.array( diff --git a/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py b/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py index 940f2bdd92..f6c93c92c5 100644 --- a/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py +++ b/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py @@ -32,12 +32,18 @@ data_type_map_file = Path(__file__).parent / "data_type_map_dpa3_pt2_nopbc.lmp" # Reference values written by source/tests/infer/gen_dpa3.py (NoPbc case). -_ref = read_expected_ref(ref_file)["nopbc"] -expected_ae = _ref["expected_e"] -expected_e = np.sum(expected_ae) -expected_f = _ref["expected_f"].reshape(6, 3) -# LAMMPS uses opposite sign convention for virial vs DeepPot atom_virial. -expected_v = -_ref["expected_v"].reshape(6, 9) +# Guarded with try/except because gen_dpa3.py only runs when PyTorch is built; +# matrices that disable PyTorch (e.g. paddle-only) skip the test in +# setup_module but still load this file at pytest collection time. +try: + _ref = read_expected_ref(ref_file)["nopbc"] + expected_ae = _ref["expected_e"] + expected_e = np.sum(expected_ae) + expected_f = _ref["expected_f"].reshape(6, 3) + # LAMMPS uses opposite sign convention for virial vs DeepPot atom_virial. + expected_v = -_ref["expected_v"].reshape(6, 9) +except FileNotFoundError: + expected_ae = expected_e = expected_f = expected_v = None box = np.array([0, 13, 0, 13, 0, 13, 0, 0, 0]) coord = np.array( diff --git a/source/lmp/tests/test_lammps_faparam_pt2.py b/source/lmp/tests/test_lammps_faparam_pt2.py index acfe032706..7f1a1d535d 100644 --- a/source/lmp/tests/test_lammps_faparam_pt2.py +++ b/source/lmp/tests/test_lammps_faparam_pt2.py @@ -38,10 +38,16 @@ # Reference values written by source/tests/infer/gen_fparam_aparam.py for the # default-fparam case. The .pth and .pt2 produce identical values (verified by # the gen script's parity check). -_ref = read_expected_ref(ref_file)["default"] -expected_ae = _ref["expected_e"] -expected_e = np.sum(expected_ae) -expected_f = _ref["expected_f"].reshape(6, 3) +# Guarded with try/except because gen_fparam_aparam.py only runs when PyTorch +# is built; matrices that disable PyTorch (e.g. paddle-only) skip the test in +# setup_module but still load this file at pytest collection time. +try: + _ref = read_expected_ref(ref_file)["default"] + expected_ae = _ref["expected_e"] + expected_e = np.sum(expected_ae) + expected_f = _ref["expected_f"].reshape(6, 3) +except FileNotFoundError: + expected_ae = expected_e = expected_f = None box = np.array([0, 13, 0, 13, 0, 13, 0, 0, 0]) coord = np.array( From 00c45a6fadb85d173fead2b54a9ea157f8c410bd Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 1 May 2026 21:39:21 +0800 Subject: [PATCH 5/7] test: address coderabbit review on PR #5428 - ASSERT_EQ size guards on expected_md_f / expected_md_v before fixed- index access in TestInferDeepPotModeDeviPtExptPrecomputed; turns a potential silent OOB into a clear gtest failure if the sidecar layout changes. - Sharper parser errors in source/lmp/tests/expected_ref.py: explicit header-token-count and payload-length checks with the file path in the message, instead of the bare ValueError / IndexError that pop out of line.split() / out-of-range indexing. --- source/api_cc/tests/test_deeppot_model_devi_ptexpt.cc | 3 +++ source/lmp/tests/expected_ref.py | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/source/api_cc/tests/test_deeppot_model_devi_ptexpt.cc b/source/api_cc/tests/test_deeppot_model_devi_ptexpt.cc index 30cc934ff3..19fbcd0b99 100644 --- a/source/api_cc/tests/test_deeppot_model_devi_ptexpt.cc +++ b/source/api_cc/tests/test_deeppot_model_devi_ptexpt.cc @@ -455,6 +455,9 @@ class TestInferDeepPotModeDeviPtExptPrecomputed : public ::testing::Test { ref.load("../../tests/infer/model_devi.expected"); expected_md_f = ref.get("default", "expected_md_f"); expected_md_v = ref.get("default", "expected_md_v"); + // gen_model_devi.py writes (max, min, avg/mystd) — 3 elements each. + ASSERT_EQ(expected_md_f.size(), 3u); + ASSERT_EQ(expected_md_v.size(), 3u); natoms = coord.size() / 3; }; diff --git a/source/lmp/tests/expected_ref.py b/source/lmp/tests/expected_ref.py index 817c2fe588..faa6ff490f 100644 --- a/source/lmp/tests/expected_ref.py +++ b/source/lmp/tests/expected_ref.py @@ -27,8 +27,17 @@ def read_expected_ref(path): continue if current_section is None: raise ValueError(f"array '{line}' before any [section] in {path}") - key, count = line.split() + parts = line.split() + if len(parts) != 2: + raise ValueError( + f"invalid array header '{line}' in {path}; expected ' '" + ) + key, count = parts n = int(count) + if i + n > len(lines): + raise ValueError( + f"array '{key}' expects {n} values, but only {len(lines) - i} remain in {path}" + ) values = [float(lines[i + j].strip()) for j in range(n)] i += n sections[current_section][key] = np.array(values, dtype=np.float64) From a444251006d428846466e566d67126dc03cab21d Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 1 May 2026 21:48:43 +0800 Subject: [PATCH 6/7] test(lmp): inline atom-energy sum to drop unused expected_ae global CodeQL flagged `expected_ae` as an unused global in the three sidecar-loading LAMMPS .pt2 tests; it was only used as the operand of np.sum() to compute expected_e. Inline the sum so there's no dangling global and the FileNotFoundError fallback no longer has to pin a stale name. --- source/lmp/tests/test_lammps_dpa3_pt2.py | 5 ++--- source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py | 5 ++--- source/lmp/tests/test_lammps_faparam_pt2.py | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/source/lmp/tests/test_lammps_dpa3_pt2.py b/source/lmp/tests/test_lammps_dpa3_pt2.py index 3f5e439790..806d3f0b46 100644 --- a/source/lmp/tests/test_lammps_dpa3_pt2.py +++ b/source/lmp/tests/test_lammps_dpa3_pt2.py @@ -37,13 +37,12 @@ # setup_module but still load this file at pytest collection time. try: _ref = read_expected_ref(ref_file)["pbc"] - expected_ae = _ref["expected_e"] - expected_e = np.sum(expected_ae) + expected_e = float(np.sum(_ref["expected_e"])) expected_f = _ref["expected_f"].reshape(6, 3) # LAMMPS uses opposite sign convention for virial vs DeepPot atom_virial. expected_v = -_ref["expected_v"].reshape(6, 9) except FileNotFoundError: - expected_ae = expected_e = expected_f = expected_v = None + expected_e = expected_f = expected_v = None box = np.array([0, 13, 0, 13, 0, 13, 0, 0, 0]) coord = np.array( diff --git a/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py b/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py index f6c93c92c5..e856b7aaf4 100644 --- a/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py +++ b/source/lmp/tests/test_lammps_dpa3_pt2_nopbc.py @@ -37,13 +37,12 @@ # setup_module but still load this file at pytest collection time. try: _ref = read_expected_ref(ref_file)["nopbc"] - expected_ae = _ref["expected_e"] - expected_e = np.sum(expected_ae) + expected_e = float(np.sum(_ref["expected_e"])) expected_f = _ref["expected_f"].reshape(6, 3) # LAMMPS uses opposite sign convention for virial vs DeepPot atom_virial. expected_v = -_ref["expected_v"].reshape(6, 9) except FileNotFoundError: - expected_ae = expected_e = expected_f = expected_v = None + expected_e = expected_f = expected_v = None box = np.array([0, 13, 0, 13, 0, 13, 0, 0, 0]) coord = np.array( diff --git a/source/lmp/tests/test_lammps_faparam_pt2.py b/source/lmp/tests/test_lammps_faparam_pt2.py index 7f1a1d535d..721afb0357 100644 --- a/source/lmp/tests/test_lammps_faparam_pt2.py +++ b/source/lmp/tests/test_lammps_faparam_pt2.py @@ -43,11 +43,10 @@ # setup_module but still load this file at pytest collection time. try: _ref = read_expected_ref(ref_file)["default"] - expected_ae = _ref["expected_e"] - expected_e = np.sum(expected_ae) + expected_e = float(np.sum(_ref["expected_e"])) expected_f = _ref["expected_f"].reshape(6, 3) except FileNotFoundError: - expected_ae = expected_e = expected_f = None + expected_e = expected_f = None box = np.array([0, 13, 0, 13, 0, 13, 0, 0, 0]) coord = np.array( From d3704b9b65ec43d183a5b77410b4ab6c24f0f623 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 1 May 2026 22:01:19 +0800 Subject: [PATCH 7/7] test(lmp): reject negative array counts in expected_ref parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeRabbit (review #4211393623) noted that a negative `count` in a sidecar array header (e.g. `expected_e -3`) would pass the existing length check (`i + n > len(lines)` is false for n<0), then `range(-3)` yields no values, and `i += -3` rewinds the read position — at best re-parsing earlier lines, at worst looping forever on a long file. Add an explicit `n < 0` guard with a clear message naming both the array and the file. --- source/lmp/tests/expected_ref.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/lmp/tests/expected_ref.py b/source/lmp/tests/expected_ref.py index faa6ff490f..777bd0ea52 100644 --- a/source/lmp/tests/expected_ref.py +++ b/source/lmp/tests/expected_ref.py @@ -34,6 +34,8 @@ def read_expected_ref(path): ) key, count = parts n = int(count) + if n < 0: + raise ValueError(f"array '{key}' has negative count {n} in {path}") if i + n > len(lines): raise ValueError( f"array '{key}' expects {n} values, but only {len(lines) - i} remain in {path}"