Skip to content

fix(pt_expt): preserve graph routing for raw checkpoints - #5912

Merged
OutisLi merged 5 commits into
deepmodeling:masterfrom
OutisLi:pr/pt-expt-infer
Jul 31, 2026
Merged

fix(pt_expt): preserve graph routing for raw checkpoints#5912
OutisLi merged 5 commits into
deepmodeling:masterfrom
OutisLi:pr/pt-expt-infer

Conversation

@OutisLi

@OutisLi OutisLi commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • preserve graph-based public-forward routing when loading graph-eligible raw PyTorch checkpoints
  • distinguish regular PT and PT-experimental checkpoint parameter dialects conservatively, with clear errors for ambiguous payloads
  • select the NV graph builder automatically on supported CUDA hosts and otherwise use the dense graph builder; Vesin remains explicit opt-in
  • reject nlist-specific controls on graph-routed models instead of silently ignoring them or changing the model's lower semantics

Compatibility

Graph-eligible raw .pt checkpoints intentionally keep the source model's graph-forward semantics. Passing neighbor_list= or a non-default nlist_backend to such a checkpoint now fails fast because switching to the nlist lower can change predictions (the root cause of #5862). Use neighbor_graph_method="ase" for ASE-based carry-all graph construction. Explicit nlist controls remain supported for nlist-routed checkpoints and deployment artifacts.

Checks

  • targeted checkpoint-routing, dialect-detection, graph-builder selection, and graph/nlist × spin/non-spin inference tests: 14 passed, 16 subtests passed
  • Ruff format and lint checks passed
  • repository pre-commit hooks passed

Summary by CodeRabbit

  • New Features
    • Added device-aware automatic inference neighbor-graph selection via neighbor_graph_method="auto" (now the default) with improved neighbor-graph metadata reporting.
    • Enabled “graph-lower” execution for eligible PT checkpoints, including support for determining graph edge precision from model characteristics.
    • Improved PT checkpoint backend handling by detecting checkpoint dialects and rejecting unsupported/undecidable cases with clearer errors.
  • Bug Fixes
    • Strengthened validation for incompatible neighbor and lower-routing configurations, with fail-fast behavior for invalid combinations.
  • Tests
    • Expanded coverage for PT checkpoint dialect detection, neighbor-graph “auto” resolution across CPU/CUDA, and negative validation cases.

OutisLi added 2 commits July 28, 2026 12:05
Select the eager lower ABI from the restored model capability instead of
forcing every raw checkpoint through the padded dense neighbor-list path.
Graph-eligible energy models now reuse the graph DeepEval contract, keeping
energy, force, virial, and atomic outputs aligned with public forward
semantics when descriptor statistics are nonzero.

Retain the existing dense and spin paths, expose graph builder selection for
raw graph checkpoints, and cover both plain and compiled checkpoint layouts
with a deterministic DPA1 regression.
Resolve the graph neighbor backend once when DeepEval loads the model. Prefer
the batched nvalchemiops builder on CUDA, fall back to Vesin when available,
and retain the dense all-pairs implementation as the dependency-free final
fallback.

This removes the single-core NumPy O(N²) graph construction bottleneck from
the default dp test path while preserving every explicit builder selection.
Cover the resolved backend in the raw DPA1 checkpoint regression.
Copilot AI review requested due to automatic review settings July 28, 2026 04:06
@dosubot dosubot Bot added the bug label Jul 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

DeepEval centralizes PT checkpoint dialect detection, graph-lower loading, neighbor backend selection, and graph metadata dtype calculation. Tests cover checkpoint routing, automatic neighbor selection, invalid option combinations, graph metadata, and eager output parity.

Changes

Graph-routed PT inference

Layer / File(s) Summary
Checkpoint dialect detection
deepmd/utils/pt_checkpoint.py, deepmd/backend/pt_expt.py, deepmd/pt_expt/infer/deep_eval.py
A shared helper classifies PT-expt, PT, and ambiguous checkpoint payloads for backend matching and DeepEval loading.
Neighbor backend selection
deepmd/pt_expt/infer/deep_eval.py
neighbor_graph_method defaults to "auto", resolves to "nv" on supported CUDA systems or "dense" otherwise, and rejects incompatible graph-routed neighbor settings.
Graph-lower checkpoint loading
deepmd/pt_expt/infer/deep_eval.py
Graph-eligible checkpoints record graph metadata and execute through eager graph-lower runners with spin and non-spin output translation.
Graph metadata dtype
deepmd/pt_expt/model/graph_lower.py, deepmd/pt_expt/utils/serialization.py
Graph edge dtype selection is exposed through graph_edge_dtype and used during metadata collection.
Regression coverage
source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py, source/tests/pt_expt/utils/test_graph_pt2_metadata.py
Tests validate dialect detection, neighbor resolution, routing constraints, graph metadata, and native-spin evaluation parity.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DeepEval
  participant PTCheckpoint
  participant NeighborBackend
  participant PTModel
  participant PublicEvaluation
  DeepEval->>PTCheckpoint: detect checkpoint dialect
  DeepEval->>PTModel: inspect graph-lower capability
  DeepEval->>NeighborBackend: resolve and configure neighbor construction
  DeepEval->>PTModel: call forward_common_lower_graph
  PTModel-->>DeepEval: return graph-lower outputs
  DeepEval->>PublicEvaluation: translate and expose evaluation results
Loading

Possibly related PRs

Suggested labels: enhancement, Core

Suggested reviewers: copilot, wanghan-iapcm

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: raw PyTorch checkpoint loading now preserves graph routing.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py (1)

342-423: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test duplicates the production resolution order.

setUpClass re-implements the autonv/vesin/dense ladder, so a regression in DeepEval._resolve_neighbor_graph_method that changes the order would be mirrored by the test and stay green. Consider asserting against DeepEval._resolve_neighbor_graph_method("auto") and covering the explicit-method path (e.g. neighbor_graph_method="dense") for the deterministic parity check.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py` around lines 342
- 423, Update TestPtExptLoadPtGraphDPA1.setUpClass to derive
expected_graph_method by calling DeepEval._resolve_neighbor_graph_method("auto")
instead of duplicating the nv/vesin/dense selection logic. Add coverage for an
explicit neighbor_graph_method="dense" configuration and assert its
deterministic method selection and evaluation parity, reusing the existing
checkpoint/test flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@deepmd/pt_expt/infer/deep_eval.py`:
- Around line 728-777: The use_graph_lower branch in _load_pt incorrectly
selects the dense _eager_runner_graph for native-spin checkpoints. Exclude
native-spin models from this branch or provide a native-spin graph runner
matching NativeSpinEnergyModel.forward_lower_graph_exportable’s 14-argument
signature, ensuring exported_module receives spin separately rather than
treating it as fparam.

---

Nitpick comments:
In `@source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py`:
- Around line 342-423: Update TestPtExptLoadPtGraphDPA1.setUpClass to derive
expected_graph_method by calling DeepEval._resolve_neighbor_graph_method("auto")
instead of duplicating the nv/vesin/dense selection logic. Add coverage for an
explicit neighbor_graph_method="dense" configuration and assert its
deterministic method selection and evaluation parity, reusing the existing
checkpoint/test flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fffcc8fd-f028-48f2-9e8b-e2448c4e79d2

📥 Commits

Reviewing files that changed from the base of the PR and between 2f419f4 and 09e9442.

📒 Files selected for processing (2)
  • deepmd/pt_expt/infer/deep_eval.py
  • source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py

Comment thread deepmd/pt_expt/infer/deep_eval.py Outdated
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.96907% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 79.00%. Comparing base (2f419f4) to head (5f37d97).
⚠️ Report is 8 commits behind head on master.

Files with missing lines Patch % Lines
deepmd/pt_expt/infer/deep_eval.py 98.41% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5912      +/-   ##
==========================================
- Coverage   79.06%   79.00%   -0.07%     
==========================================
  Files        1067     1070       +3     
  Lines      123805   124123     +318     
  Branches     4510     4527      +17     
==========================================
+ Hits        97891    98064     +173     
- Misses      24304    24440     +136     
- Partials     1610     1619       +9     

☔ 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.

Copilot AI review requested due to automatic review settings July 28, 2026 06:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

@OutisLi
OutisLi requested a review from wanghan-iapcm July 28, 2026 06:40

@njzjz-bot njzjz-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Requesting changes for the inline raw-checkpoint routing issue.

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

Comment thread deepmd/pt_expt/infer/deep_eval.py Outdated
Copilot AI review requested due to automatic review settings July 28, 2026 12:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
deepmd/backend/pt_expt.py (1)

32-71: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add focused tests for every detector outcome.

This helper now controls both backend auto-dispatch and .pt loading. Cover wrapped checkpoints, .w, .matrix, bias-only, mixed, and non-string-key cases to prevent silent misrouting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deepmd/backend/pt_expt.py` around lines 32 - 71, Add focused tests for
detect_pt_checkpoint_backend covering every outcome: wrapped checkpoints under
“model”, unambiguous .w and .matrix weights, bias-only .b and .bias states,
mixed/ambiguous keys returning None, and mappings containing non-string keys.
Assert the expected backend or None for each case, including both wrapped and
unwrapped payload behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py`:
- Around line 754-761: Update the test around DeepPot initialization to assert
that the resolved neighbor-graph method is “dense,” not only that metadata
reports graph input. Use the DeepPot-resolved method symbol exposed by the
existing API, preserving the explicit neighbor_graph_method="dense" setup and
current assertions.

---

Nitpick comments:
In `@deepmd/backend/pt_expt.py`:
- Around line 32-71: Add focused tests for detect_pt_checkpoint_backend covering
every outcome: wrapped checkpoints under “model”, unambiguous .w and .matrix
weights, bias-only .b and .bias states, mixed/ambiguous keys returning None, and
mappings containing non-string keys. Assert the expected backend or None for
each case, including both wrapped and unwrapped payload behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8280e232-c6d8-4b66-9991-cfefe05b349b

📥 Commits

Reviewing files that changed from the base of the PR and between 7c48a6c and 8ef72a3.

📒 Files selected for processing (3)
  • deepmd/backend/pt_expt.py
  • deepmd/pt_expt/infer/deep_eval.py
  • source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • deepmd/pt_expt/infer/deep_eval.py

Comment thread source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py
Comment thread deepmd/pt_expt/infer/deep_eval.py Fixed

@njzjz-bot njzjz-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The latest commit distinguishes raw checkpoint backends by parameter dialect, makes the pt_expt native-spin DPA4 runner reachable, and adds an end-to-end dispatch and inference regression test. The earlier blocker is resolved.

Focused validation: backend-dispatch tests and native-spin DPA4 checkpoint inference passed.

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

@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.

The routing fix is the right diagnosis and the weight-name dispatch is a genuine improvement. Raw .pt was hardcoded to lower_input_kind="nlist" since #5562, so a model trained on the graph lower was being evaluated through the dense path - and the old has_pt_expt and not has_pt rule mis-handed pt_expt DPA4 checkpoints to the pt backend, because they legitimately carry torch-native .bias alongside dpmodel .w. Making weight names decisive fixes that; I confirmed pt's SeZM/DPA4 routes through MLPLayer and so carries .matrix, and that freshly built state dicts for pt and pt_expt across dpa2 and DPA4-native-spin all classify correctly.

Two blocking comments, on the dispatch inconsistency and on the untested new guards. Eight further comments inline.

Worth stating plainly, because it frames several of the others: this PR changes the default evaluation path for every graph-eligible artifact, not only the raw .pt files it set out to fix. neighbor_graph_method flips from "dense" to a device-aware "auto", so the builder now depends on the host and on which optional packages happen to be installed. The builders are asserted to be edge-set equivalent, but the graph lower accumulates through segment_sum over edges, so ordering differences alone move fp64 results - and nothing in the PR asserts that dense, vesin and nv agree. The one test that touches this is tautological (see the comment on _resolve_neighbor_graph_method).

A couple of things I checked and want to record as clear, so they are not re-raised:

  • Virtual-atom spin models do not misroute into the native-spin graph runner. SpinModel.__init__ calls descriptor.disable_graph_lower() and _graph_lower_disabled is a persisted buffer restored by load_state_dict before the check, so model_uses_graph_lower correctly returns False for them.
  • The earlier bot concern that the native-spin fix was dead code - because _load_pt rejected DPA4/SeZM before that branch - was true at 7c48a6c but is resolved at head by the final commit, which does exactly what that comment asked. The branch is reachable and has a regression test.
  • CI did run on this PR: 11 passing, 2 skipping, and the single failure is a Read the Docs build, not a test. The "Checks: not run per request" note refers to local runs.

Smaller notes:

  1. When no .w and no .matrix key exists, the bias-only fallback returns "pt" for anything carrying .bias, and _load_pt then tells the user to load it with dp --pt. That is safe today only because every pt_expt layer is a NativeLayer using .w/.b. A pt_expt model that became fully torch-native would be refused by its own backend, pointed at the wrong one. Returning None for "unknown" would fail soft instead.

  2. .pt files are fully torch.loaded twice during dispatch - once in match_filename and again in _load_pt. Pre-existing, but this PR adds a second detect_pt_checkpoint_backend pass on top, and on multi-GB checkpoints backend selection alone pays a full deserialization.

  3. Codecov reports 81.43% patch coverage with 13 newly-added lines uncovered, 7 of them in deepmd/backend/pt_expt.py - consistent with the coverage gaps in the two blocking comments.

Comment thread deepmd/backend/pt_expt.py Outdated
Comment thread deepmd/pt_expt/infer/deep_eval.py Outdated
Comment thread deepmd/pt_expt/infer/deep_eval.py Outdated
Comment thread deepmd/pt_expt/infer/deep_eval.py
Comment thread deepmd/pt_expt/infer/deep_eval.py Outdated
Comment thread deepmd/pt_expt/infer/deep_eval.py Outdated
Comment thread deepmd/pt_expt/infer/deep_eval.py Outdated
Comment thread deepmd/pt_expt/infer/deep_eval.py
Comment thread deepmd/pt_expt/infer/deep_eval.py
Comment thread deepmd/pt_expt/infer/deep_eval.py Outdated

@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.

One readability note on the eager-runner dispatch.

Comment thread deepmd/pt_expt/infer/deep_eval.py Outdated
Copilot AI review requested due to automatic review settings July 30, 2026 04:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

OutisLi commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up to the review summary, implemented in 5f37d97b4:

  • The bias-only fallback is now conservative: .b alone identifies pt_expt, while .bias alone returns None because torch-native modules can occur in pt_expt checkpoints. Weight names remain decisive, so pt_expt DPA4 (.w plus ordinary .bias) still routes correctly.
  • The double torch.load during automatic backend dispatch remains unchanged. It predates this fix, and eliminating it cleanly requires the dispatcher to hand the loaded payload to the selected backend (or another explicit ownership/lifetime design); a process-level checkpoint cache would add memory and invalidation risks and is outside this routing-correctness PR.
  • The previously uncovered verdict and guard branches now have focused coverage. Together with the four graph/nlist × spin/non-spin runner checks, the targeted run completed with 14 passed tests and 16 passed subtests.

The PR description now also records the graph/nlist compatibility contract and directs ASE graph users to neighbor_graph_method="ase".

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
deepmd/pt_expt/infer/deep_eval.py (1)

246-259: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a single _is_graph_routed helper.

The lower_input_kind in ("graph", "dpa1_canonical") classification is now encoded here and again in _setup_neighbor_backend (Line 318), and _eval_model/_eval_model_spin use slightly different variants (_eval_model_spin checks only "graph"). A single accessor would keep these in sync.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deepmd/pt_expt/infer/deep_eval.py` around lines 246 - 259, Add a shared
_is_graph_routed helper and use it for all lower_input_kind classification.
Replace the inline check in the current validation and the duplicate logic in
_setup_neighbor_backend, _eval_model, and _eval_model_spin, preserving graph and
dpa1_canonical as graph-routed kinds consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@deepmd/pt_expt/infer/deep_eval.py`:
- Around line 246-259: Add a shared _is_graph_routed helper and use it for all
lower_input_kind classification. Replace the inline check in the current
validation and the duplicate logic in _setup_neighbor_backend, _eval_model, and
_eval_model_spin, preserving graph and dpa1_canonical as graph-routed kinds
consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9d6be660-788d-4192-a41d-a93af6bf7bbc

📥 Commits

Reviewing files that changed from the base of the PR and between 8ef72a3 and 5f37d97.

📒 Files selected for processing (7)
  • deepmd/backend/pt_expt.py
  • deepmd/pt_expt/infer/deep_eval.py
  • deepmd/pt_expt/model/graph_lower.py
  • deepmd/pt_expt/utils/serialization.py
  • deepmd/utils/pt_checkpoint.py
  • source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py
  • source/tests/pt_expt/utils/test_graph_pt2_metadata.py

@OutisLi
OutisLi requested a review from wanghan-iapcm July 30, 2026 05:42

@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.

Verified all eleven at 5f37d97b4. The nine you agreed with are genuinely fixed, and I accept both of the ones you pushed back on.

The routing foundation is now right. Moving the detector into deepmd/utils/pt_checkpoint.py so dispatch and loading share one verdict was the important part, and _load_pt rejects the explicit pt verdict and the indeterminate one separately, before _extra_state parsing, so a forced dp --pt-expt foo.pt no longer reaches load_state_dict with an opaque failure. The bias asymmetry is better than what I asked for: treating a lone .b as pt_expt-specific while leaving a lone .bias unclassified is conservative in the safe direction, since pt_expt models legitimately contain torch-native modules.

The rest check out as described: Vesin is out of the auto cascade and auto now resolves to NV only on a CUDA host with the package present; an explicit nlist_backend on a graph-routed model raises rather than being ignored; dense is no longer silently accepted on an nlist artifact now that auto is the default; the unreachable is_native_spin_graph condition is gone; and the runner dispatch nests on lower ABI then spin, with all four quadrants covered by test classes. The mocked CPU / CUDA+NV / CUDA-without-NV resolution test replaces the tautological host-dependent assertion, which was the actual problem there.

On the two you did not take:

Keeping neighbor_list= as a hard failure is the right call. My concern was that a working call becomes a construction error, but the old call could produce badly wrong energies for graph-native DPA1 with nonzero descriptor statistics, and failing loudly beats returning plausible garbage. The error now names neighbor_graph_method='ase' and the exported nlist artifact as the two real alternatives, and the break is written down in the PR body, which is what I was actually asking for.

I also accept not reusing _supports_graph_export for eager routing. Exportability and reproducing the source model's public forward are different questions, and applying the export gate here would push raw checkpoints back onto the nlist lower and reintroduce #5862. What remains is that a compressed DPA1 can be frozen to an nlist artifact while eager evaluation of the same model takes the graph lower; I read that as a limitation of the export path rather than something this PR should carry.

On coverage: TestPtExptLoadPtGraphDPA1::test_eval_matches_public_forward is the test that pins the original defect, since it compares a raw .pt evaluation against the source model's public forward for a graph-native descriptor -- the comparison nothing made before, which is why the unconditional lower_input_kind = "nlist" went unnoticed.

@OutisLi
OutisLi enabled auto-merge July 30, 2026 16:17
@OutisLi
OutisLi added this pull request to the merge queue Jul 30, 2026
Merged via the queue into deepmodeling:master with commit cf3e6f1 Jul 31, 2026
58 checks passed
@OutisLi
OutisLi deleted the pr/pt-expt-infer branch July 31, 2026 04:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants