Skip to content

fix(dpmodel): support parameter shorthand in DeepEval#5853

Open
njzjz-bot wants to merge 2 commits into
deepmodeling:masterfrom
njzjz-bot:fix/dpmodel-deepeval-param-shorthand-5662
Open

fix(dpmodel): support parameter shorthand in DeepEval#5853
njzjz-bot wants to merge 2 commits into
deepmodeling:masterfrom
njzjz-bot:fix/dpmodel-deepeval-param-shorthand-5662

Conversation

@njzjz-bot

Copy link
Copy Markdown
Contributor

Closes #5662.

Summary

  • normalize documented fparam and aparam shorthand into canonical frame-major arrays before automatic batching
  • preserve full per-frame inputs while tiling shared frame, per-atom, and all-atom parameter forms
  • reject invalid sizes with explicit parameter-shape errors before NumPy reshape failures
  • add direct dpmodel backend regressions with two-dimensional parameters, split/unsplit execution, and list input

Why existing tests missed this

Normal public DeepEval/DeepPot calls pass through _standard_input, which already tiles shorthand before invoking a backend and therefore masks the dpmodel adapter defect. Existing .dp consistency coverage uses one frame with full parameter shapes. No regression called the low-level dpmodel backend directly with multiple frames, nor forced automatic batching while passing (natoms, dim_aparam), which the batcher otherwise mistakes for a frame-major array and slices along the atom axis.

Validation

  • pytest source/tests/infer/test_dpmodel_deep_eval_params.py -q (8 passed)
  • public multi-frame DeepEval compatibility smoke test with forced one-frame batches (passed)
  • ruff format . (1 new test file reformatted; 1663 files unchanged)
  • ruff check . (passed)
  • git diff --check (passed)

Coding agent: Codex
Codex version: codex-cli 0.144.4
Model: gpt-5.6-sol
Reasoning effort: xhigh

njzjz-bot and others added 2 commits July 17, 2026 07:15
Normalize documented frame and atomic parameter shorthand before automatic
batching. Add direct-backend coverage for shared inputs, forced batch splits,
and invalid parameter sizes.

Coding-Agent: Codex
Codex-Version: codex-cli 0.144.4
Model: gpt-5.6-sol
Reasoning-Effort: xhigh
@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.33%. Comparing base (6c3b985) to head (1eb3feb).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5853      +/-   ##
==========================================
- Coverage   78.58%   78.33%   -0.25%     
==========================================
  Files        1050     1050              
  Lines      120637   120654      +17     
  Branches     4356     4356              
==========================================
- Hits        94801    94515     -286     
- Misses      24278    24579     +301     
- Partials     1558     1560       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@njzjz

njzjz commented Jul 18, 2026

Copy link
Copy Markdown
Member

Possible reviewers based on changed lines, exact file history, and exact-file review history:

  • @wanghan-iapcm — 5 commits on changed files; 26 reviews on exact changed files (deepmd/dpmodel/infer/deep_eval.py).
  • @iProzd — 3 commits on changed files (deepmd/dpmodel/infer/deep_eval.py).

No review request was made automatically.

Coding agent: Codex
Codex version: codex-cli 0.144.4
Model: gpt-5.6-sol
Reasoning effort: xhigh

@njzjz
njzjz requested review from iProzd and wanghan-iapcm and removed request for iProzd and wanghan-iapcm July 18, 2026 07:26

@wanghan-iapcm wanghan-iapcm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Retracted - posted prematurely. Please disregard; review pending.

@wanghan-iapcm wanghan-iapcm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Fix is correct. AutoBatchSize.execute_all slices only ndim > 1 args along axis 0, so a (natoms, dim_aparam) shorthand really was being sliced on its atom axis - canonicalizing before the batcher is the right place. I checked the size-dispatch for ambiguity: collisions occur only at n == 1 or natoms == 1, and in each the two branches produce the identical array, so the check order is safe. Predicate order matches _standard_input, so the public path stays idempotent with no double-tiling. All 8 new tests fail pre-fix, verified against an unpatched tree.

Two comments inline.

Merge ordering with #5852. It inserts at this same anchor and rewrites the out = self._eval_func(...) call this diff carries as context; git merge-tree confirms a real conflict, not just adjacency. Both PRs exist for the same reason - AutoBatchSize slices only frame-axis arrays - and spin is likewise unnormalized in _standard_input. Canonicalizing in the shared layer would cover spin, fparam and aparam together and collapse both PRs into one change.

Minor:

  1. _standard_input emits aparam as 2-D (nframes, natoms * dim_aparam); this returns 3-D. _eval_model reshapes either way, but it changes the internal boundary #4285 established without documenting it.

  2. AutoBatchSize.__init__ takes current_batch_size from DP_INFER_BATCH_SIZE when set, overriding the constructor argument. Under that env var the auto_batch_size=6 case stops splitting and silently becomes a duplicate of False, so the only batching coverage disappears with no failure. monkeypatch.delenv("DP_INFER_BATCH_SIZE", raising=False) plus an assertion on the _eval_model call count would pin it.

  3. Validation is size-only, so a transposed (dim_fparam, nframes) array passes and is reinterpreted row-major. Matches _standard_input, so not a regression, but it sits against the stated goal of explicit shape errors.

natoms, numb_test = self._get_natoms_and_nframes(
coords, atom_types, len(atom_types.shape) > 1
)
# Canonicalize documented shorthand before AutoBatchSize sees it.

@wanghan-iapcm wanghan-iapcm Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This ladder already exists in DeepEval._standard_input (deepmd/infer/deep_eval.py) - same three-way dispatch, same tiling, same wording. That placement was deliberate: #3213 put canonicalization in _standard_input, #3356 added this ladder there for every backend, and #4285 gave this adapter only the bare reshape because it consumes already-rectangular arrays.

The gap isn't dpmodel-specific. All three siblings reshape without tiling:

  • deepmd/pt/infer/deep_eval.py:695
  • deepmd/jax/infer/deep_eval.py:411
  • deepmd/pd/infer/deep_eval.py:544

while DeepEvalBackend.eval's docstring - the contract all of them implement - documents all three shorthands. So after this PR deep_eval.eval(fparam=<1-D>) succeeds on .dp and raises on .pth.

I'd rather see this fixed once in the shared layer than per backend: a DeepEvalBackend._canonicalize_params(fparam, aparam, nframes, natoms) called from each backend's eval covers all five at once. As written this is the third copy, and the copies already disagree - _standard_input says "frame param" where this says "atomic param", so the same bad input reports differently depending on entry point.

).reshape(len(ATOM_TYPES), 3)
BOX = np.diag([13.0, 13.0, 13.0])
NFRAMES = 2
COORDS = np.tile(COORD, (NFRAMES, 1, 1))

@wanghan-iapcm wanghan-iapcm Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

COORDS = np.tile(COORD, (NFRAMES, 1, 1)) makes both frames byte-identical, and every test's parameters are frame-invariant, so nothing here distinguishes correct frame-major handling from "use frame 0's parameters everywhere".

The tests do fail pre-fix, but as a crash (cannot reshape array of size 2 into shape (1,6,2)), not as a wrong number - a regression that kept the shapes right while losing per-frame variation would pass all 8.

One case closes it: fparam (NFRAMES, dim) with distinct rows and aparam (NFRAMES, natoms, dim) with distinct frames, split vs unsplit, asserting both that the two agree and that the per-frame energies differ. The second assertion is what makes the first meaningful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Code scan] Honor documented fparam/aparam shorthand in dpmodel DeepEval

3 participants