Skip to content

test(pw): add a DeltaSpin onsite stress oracle test - #8137

Merged
mohanchen merged 1 commit into
deepmodeling:developfrom
mintleaf84:test/deltaspin-stress-oracle
Oct 13, 2026
Merged

mohanchen merged 1 commit into
deepmodeling:developfrom
mintleaf84:test/deltaspin-stress-oracle

Conversation

@mintleaf84

Copy link
Copy Markdown

Reminder

  • I have read AGENTS.md and docs/developers_guide/agent_governance.md.
  • I have linked an issue or explained why this PR does not need one.
  • I have added adequate unit tests and/or case tests, or explained why not.
  • I have listed the exact verification commands run and their results.
  • I have described user-visible behavior changes, including INPUT parameter changes.
  • I have explained core-module impact for ESolver, HSolver, ElecState, Hamilt, Operator, Psi, or other source/ changes.
  • I have requested any needed governance exception below.

Linked Issue

Follow-up to #8133 and to #8125; no new issue is opened for this test gap, and this PR does not change any production code.

What's changed?

#8122 fixed the DeltaSpin Pauli-y signs in the PW onsite force kernels and shipped an independent oracle for them (kernels/test/test_force_op.cpp differentiates physical Pauli moments by hand and compares against the kernel). The stress side never got the same treatment: kernels/test/stress_op_test.cpp contains no reference to lambda at all, so the sign correction in #8125, and by extension the ROCm sync in #8133, has no test that would fail if it were reverted.

This PR adds the missing twin:

  • source/source_pw/module_pwdft/kernels/test/test_stress_op.cpp (new)
  • source/source_pw/module_pwdft/kernels/test/CMakeLists.txt: register deltaspin_stress_cpu_test, next to the existing deltaspin_force_cpu_test so it inherits the same feature-define context

The fixture drives hamilt::cal_stress_nl_op<double, DEVICE_CPU> in its DeltaSpin form over both spinor projectors and one collinear projector, for each of the three Pauli channels, and compares against -1/2 d/d eps [ sum_ib w * lambda . M(b + eps*db) ], where M = b^dagger sigma b is built in the test from the Pauli matrices without borrowing any indexing from the kernel. Starting the output at 0.125 also pins that the kernel accumulates rather than overwrites.

User-visible behavior

None. Test-only change; no INPUT parameter, no documented behavior, so no documentation update required.

Verification

Compiled and executed locally with the repository's own source files. No ABACUS build was configured, so this did not go through CTest; the exact commands:

$ g++ -std=c++11 -O0 -I/tmp/dsbuild/gt_inc -I. -Isource \
    source/source_pw/module_pwdft/kernels/test/test_stress_op.cpp \
    source/source_pw/module_pwdft/kernels/stress_op.cpp \
    /tmp/dsbuild/gt_main.cpp -o /tmp/dsbuild/stress_test
$ /tmp/dsbuild/stress_test
[ RUN      ] DeltaSpinStress.CpuDoubleEnergyDerivative
[       OK ] DeltaSpinStress.CpuDoubleEnergyDerivative
[  PASSED  ] all cases

-Wall -Wextra on the new file produces no warning of its own (only two pre-existing -Wunused-variable notes from source_base/module_device/memory_op.h).

/tmp/dsbuild/gt_inc/gtest/gtest.h is a ~100-line stand-in for gtest, written only because this machine has no GTest installed; it implements TEST, EXPECT_NEAR, EXPECT_EQ and the failure counter, and it is not part of the PR. CI runs the real gtest through the CMake target.

The test was checked against four mutants of stress_op.cpp, each a one-expression change in the DeltaSpin branch, and each fails exactly the channel it corrupts:

mutant failing case
coefficients1/2 reverted to the pre-#8125 signs (what ROCm had until #8133) npol=2 axis=1 only
coefficients1/2 real parts negated npol=2 axis=0 only
coefficients0/3 (lambda_z diagonal) negated npol=2 axis=2 only
local_stress -= ... flipped to += all three axes

Reproduce a mutant by copying stress_op.cpp, applying the sign change, and rerunning the compile above with the copy in place of the original.

Unit Tests and/or Case Tests for my changes

  • Commands run: the compile-and-run above, the four mutant runs, python3 tools/03_code_analysis/agent_governance_check.py --base <pre> --head <post> --event-path <this body> --format text -> Agent governance check: no findings., and python3 tools/03_code_analysis/code_quality_score.py source/source_pw/module_pwdft/kernels/test/test_stress_op.cpp -> 1 files scanned, 1 passing (threshold 60).
  • Result summary: the DeltaSpin stress kernel now agrees with an externally computed derivative of lambda . M for all three channels, in both spinor and collinear form, and the test demonstrably fails on each of the four injected errors.
  • Checks not run, with reason: no CUDA/GPU case is added here, because AddTest(... ../cuda/stress_op.cu) cannot be compiled on this machine (no nvcc) and I would rather not commit a second target whose numbers I have not seen. The force test's GPU half is the template to follow for that, and it is the change that would also be needed before a ROCm runner exists.

Governance Notes

  • INPUT/docs changes: none; no documentation update required.
  • Core module impact: none in source/ production code. The only non-test edit is the CMake registration, which is required for the new file to be built (AGENTS.md: source additions must be wired through the relevant CMakeLists.txt).
  • Exceptions requested: none.

Two limits of this test, stated plainly

  1. The overall factor of 1/2 is calibrated, not derived. All three branches of cal_stress_nl_op (DFT+U, collinear, DeltaSpin) use fac = d_wg without the explicit 2.0 * tpiba the force kernel uses, so the kernel returns -1/2 dE/d(eps) for the strain component its dbecp was built from. The test compares against that same convention, which means it pins the signs and the channel structure -- the thing that was actually broken -- and would not notice a normalization error shared by all three branches. Nothing in tests/17_DS_DFTU currently exercises test_stress either, so there is no external anchor to pin the normalization against yet.
  2. It only covers double. The DeltaSpin stress overload is declared const double* lambda in stress_op.h:141 and stress_op.h:359 but defined const FPTYPE* lambda in stress_op.cpp:345, while the force equivalent uses FPTYPE in both. cal_stress_nl_op<float, DEVICE_CPU> is explicitly instantiated (stress_op.cpp:759), yet no caller can reach its DeltaSpin overload through the header:
$ cat > /tmp/p_f.cpp   # call with float lambda through stress_op.h
$ g++ -std=c++11 -fsyntax-only -I. -Isource /tmp/p_f.cpp
stress_op.h:141:11: note: no known conversion for argument 11 from 'float [3]' to 'const double*'

and the same call with double compiles. The CUDA and ROCm copies also use const double*, so FPTYPE in the CPU definition is the odd one out; aligning the five sites is a separate, mechanical change and I left it out of a test PR.

deepmodeling#8122 shipped a finite-difference check of the DeltaSpin force kernel against
physically built Pauli moments; the stress side got no equivalent, so the sign
correction in deepmodeling#8125 and the ROCm sync in deepmodeling#8133 have nothing that would fail if
they were reverted. test_stress_op.cpp differentiates lambda . M from the
spinor and compares, for each Pauli channel and for the collinear projector.
Registered as deltaspin_stress_cpu_test beside the force target.
Copilot AI balanced review requested due to automatic review settings October 13, 2026 04:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@mohanchen mohanchen added Refactor Refactor ABACUS codes Tests/Examples Issues/PR related to unit tests and integrate tests labels Oct 13, 2026
@mohanchen
mohanchen merged commit 588bc43 into deepmodeling:develop Oct 13, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Refactor Refactor ABACUS codes Tests/Examples Issues/PR related to unit tests and integrate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants