Skip to content

Conversation

@njzjz
Copy link
Member

@njzjz njzjz commented Jan 8, 2026

Summary by CodeRabbit

  • Refactor

    • Consolidated duplicated utilities by re-exporting shared implementations to simplify maintenance.
  • Bug Fixes

    • Improved device/dtype consistency for array operations and masks to ensure tensors are placed and computed correctly across backends.
    • Fixed edge-case handling to avoid errors on empty data and improved reuse of exclusion masks for correctness.
  • New Features

    • Added a convenient public alias for mask-building functionality.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 8, 2026

📝 Walkthrough

Walkthrough

Device-placement and dtype consistency improvements across dpmodel utilities via array_api_compat; PyTorch env_mat_stat now re-exports dpmodel implementations; a public alias was added to PairExcludeMask; region.normalize_coord uses a device- and dtype-matched scalar.

Changes

Cohort / File(s) Summary
Device handling in dpmodel utils
deepmd/dpmodel/utils/env_mat_stat.py, deepmd/dpmodel/utils/nlist.py
Replaced direct .size and default-array creations with array_api_compat.size(...) and explicit device=array_api_compat.device(...) for array ops (eye, ones, arange, outer, asarray, etc.). Ensures tensors (zero_mean, one_stddev, type_idx/aidx, ghost computations, concatenation/padding, rr/nlist) are allocated on the correct device.
dpmodel exclude mask device fix
deepmd/dpmodel/utils/exclude_mask.py
In PairExcludeMask.build_type_exclude_mask, the virtual-type column now uses a device-matched xp.ones(..., device=array_api_compat.device(atype_ext)) to ensure correct device placement when extending type arrays.
PyTorch env_mat_stat re-export
deepmd/pt/utils/env_mat_stat.py
Removed local EnvMatStat/EnvMatStatSe implementations and now import/re-export them from deepmd.dpmodel.utils.env_mat_stat; module reduced to __all__ = ["EnvMatStat", "EnvMatStatSe"].
PyTorch exclude_mask alias
deepmd/pt/utils/exclude_mask.py
Added class-level alias build_type_exclude_mask = forward on PairExcludeMask (exposes alternate public name; no behavior change).
Region dtype/device consistency
deepmd/dpmodel/utils/region.py
normalize_coord now uses xp.ones((), dtype=icoord.dtype, device=array_api_compat.device(icoord)) for the remainder operand to match icoord dtype and device.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • iProzd
  • wanghan-iapcm
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely captures the main change: refactoring the PyTorch module to reuse the dpmodel EnvMatStat implementation, which is the primary objective of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the PyTorch implementation to reuse the dpmodel EnvMatStat classes, eliminating code duplication. Additionally, it improves array API compatibility by adding device parameters to array creation functions.

  • Replaced PT-specific EnvMatStat and EnvMatStatSe implementations with imports from dpmodel
  • Added build_type_exclude_mask method alias in PT's PairExcludeMask to match dpmodel interface
  • Enhanced array API compatibility by adding device parameters to array creation functions in dpmodel utilities

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
deepmd/pt/utils/env_mat_stat.py Removed duplicate implementation; now imports EnvMatStat classes from dpmodel
deepmd/pt/utils/exclude_mask.py Added build_type_exclude_mask method alias to align with dpmodel interface
deepmd/dpmodel/utils/nlist.py Added device parameters to array creation functions (eye, ones, arange, asarray) and replaced .size with array_api_compat.size()
deepmd/dpmodel/utils/env_mat_stat.py Added device parameters to array creation functions (zeros, ones, arange) and replaced .size with array_api_compat.size()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov
Copy link

codecov bot commented Jan 8, 2026

Codecov Report

❌ Patch coverage is 86.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.93%. Comparing base (8f021aa) to head (21b4c06).
⚠️ Report is 5 commits behind head on master.

Files with missing lines Patch % Lines
deepmd/dpmodel/utils/env_mat_stat.py 80.00% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #5139   +/-   ##
=======================================
  Coverage   81.93%   81.93%           
=======================================
  Files         712      712           
  Lines       72864    72831   -33     
  Branches     3617     3616    -1     
=======================================
- Hits        59700    59675   -25     
+ Misses      12001    11993    -8     
  Partials     1163     1163           

☔ View full report in Codecov by Sentry.
📢 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 marked this pull request as draft January 8, 2026 18:18
@njzjz njzjz marked this pull request as ready for review January 10, 2026 16:42
@njzjz njzjz requested review from iProzd and wanghan-iapcm January 10, 2026 16:42
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
deepmd/dpmodel/utils/exclude_mask.py (1)

115-148: Add device placement for self.type_mask and include missing axis=0 parameter.

The device mismatch is real: self.type_mask remains a host NumPy array while nlist/atype_ext may be on GPU. This is evidenced by existing workarounds in env_mat_stat.py (lines 196–198) that manually convert type_mask before calling build_type_exclude_mask. The fix should move this conversion into the method itself.

Additionally, line 145 is missing the axis=0 parameter used in AtomExcludeMask.build_type_exclude_mask (line 57), which should be added for consistency.

Proposed fix
         type_ij = xp.reshape(type_ij, (nf, nloc * nnei))
+        type_mask = xp.asarray(
+            self.type_mask,
+            device=array_api_compat.device(atype_ext),
+        )
         mask = xp.reshape(
-            xp.take(self.type_mask[...], xp.reshape(type_ij, (-1,))),
+            xp.take(type_mask, xp.reshape(type_ij, (-1,)), axis=0),
             (nf, nloc, nnei),
         )
         return mask
🤖 Fix all issues with AI agents
In @deepmd/dpmodel/utils/env_mat_stat.py:
- Around line 99-110: The ValueError raised when self.last_dim is invalid
contains a typo ("raial-only") and a vague message; update the exception in the
branch that sets radial_only to instead raise a clearer message like "last_dim
must be 1 (radial-only) or 4 (full descriptor)" to correct the typo and tighten
the wording, ensure the ValueError is a single concise string (no trailing
period needed), and keep the surrounding logic that sets radial_only based on
self.last_dim intact.
🧹 Nitpick comments (1)
deepmd/dpmodel/utils/env_mat_stat.py (1)

193-207: Nice: reuse a single PairExcludeMask + move type_mask onto the right device; consider sourcing device from extended_atype

Right now you use device=array_api_compat.device(atype); using extended_atype (or nlist) would be a bit clearer/safer if any future refactor changes where atype lives.

Small refinement
@@
                 pair_exclude_mask.type_mask = xp.asarray(
                     pair_exclude_mask.type_mask,
-                    device=array_api_compat.device(atype),
+                    device=array_api_compat.device(extended_atype),
                 )
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c690b5d and 21b4c06.

📒 Files selected for processing (2)
  • deepmd/dpmodel/utils/env_mat_stat.py
  • deepmd/dpmodel/utils/exclude_mask.py
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: njzjz
Repo: deepmodeling/deepmd-kit PR: 4144
File: source/api_cc/tests/test_deeppot_dpa_pt.cc:166-246
Timestamp: 2024-09-19T04:25:12.408Z
Learning: Refactoring between test classes `TestInferDeepPotDpaPt` and `TestInferDeepPotDpaPtNopbc` is addressed in PR #3905.
Learnt from: njzjz
Repo: deepmodeling/deepmd-kit PR: 4144
File: source/api_cc/tests/test_deeppot_dpa_pt.cc:166-246
Timestamp: 2024-10-08T15:32:11.479Z
Learning: Refactoring between test classes `TestInferDeepPotDpaPt` and `TestInferDeepPotDpaPtNopbc` is addressed in PR #3905.
Learnt from: njzjz
Repo: deepmodeling/deepmd-kit PR: 4406
File: deepmd/dpmodel/array_api.py:51-53
Timestamp: 2024-11-23T00:01:06.984Z
Learning: In `deepmd/dpmodel/array_api.py`, the `__array_api_version__` attribute is guaranteed by the Array API standard to always be present, so error handling for its absence is not required.
Learnt from: njzjz
Repo: deepmodeling/deepmd-kit PR: 4204
File: deepmd/dpmodel/fitting/general_fitting.py:426-426
Timestamp: 2024-10-10T22:46:03.419Z
Learning: In `deepmd/dpmodel/fitting/general_fitting.py`, when using the Array API and `array_api_compat`, the `astype` method is not available as an array method. Instead, use `xp.astype()` from the array namespace for type casting.
🪛 Ruff (0.14.10)
deepmd/dpmodel/utils/env_mat_stat.py

104-106: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (3)
deepmd/dpmodel/utils/env_mat_stat.py (3)

58-65: array_api_compat.size(vv) is a solid portability fix


111-129: Device-aware zero_mean/one_stddev init looks correct


184-191: The device= parameter on xp.arange() is standard-compliant and working correctly.

The Array API standard specifies device= as an optional parameter on creation routines like arange(). The deepmd-kit codebase already uses this pattern extensively across multiple files (nlist.py, exclude_mask.py, region.py, etc.) with no reported issues. The pattern device=array_api_compat.device(atype) correctly ensures the created array is placed on the same device as the reference array—NumPy safely ignores it (CPU-only), while torch/cupy respect it for proper device placement.

@iProzd iProzd enabled auto-merge January 12, 2026 03:30
@iProzd iProzd added this pull request to the merge queue Jan 12, 2026
Merged via the queue into deepmodeling:master with commit 88367a6 Jan 12, 2026
76 checks passed
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.

3 participants