Skip to content

fix(pt): allow concurrent stat cache reads#5773

Open
OutisLi wants to merge 2 commits into
deepmodeling:masterfrom
OutisLi:pr/stat
Open

fix(pt): allow concurrent stat cache reads#5773
OutisLi wants to merge 2 commits into
deepmodeling:masterfrom
OutisLi:pr/stat

Conversation

@OutisLi

@OutisLi OutisLi commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

What

  • Add the PyTorch-only training.stat_file_mode option with update (default) and read-only read modes.
  • Centralize statistics-cache path preparation, require an existing cache in read mode, and open it without write access.
  • Guard HDF5 cache save and directory-creation operations against read-only paths.
  • Update the DPA4 water example and add coverage for default/update behavior, read-only access, missing caches, and configuration validation.

Why

Multiple PyTorch training processes may need to consume the same completed statistics cache concurrently. Opening the cache in update mode permits writes and can cause HDF5 contention or accidental mutation. A read-only mode lets workers share an existing cache safely while preserving the current writable behavior for cache creation and updates.

Impact

  • Omitting stat_file_mode keeps the existing update behavior.
  • stat_file_mode: "read" requires a complete existing cache and rejects writes or directory creation.
  • The option is exposed through input validation and is supported by the PyTorch training path.

Checks

  • Added unit coverage for writable defaults, read-only cache access, missing-cache errors, and configuration normalization.
  • Tests were not rerun in this checkout per request.

Summary by CodeRabbit

  • New Features
    • Added stat_file_mode (update/read) to control how the statistics cache is used.
    • Read mode safely reuses an existing statistics cache across multiple processes.
  • Bug Fixes
    • Read-only cache paths now reject write operations.
    • Clear errors are raised in read mode when stat_file is missing, the cache is incomplete, or required statistics items are absent.
  • Documentation
    • Updated the water DPA4 example to explicitly set stat_file_mode: "update".
  • Tests
    • Added coverage for stat_file_mode validation and read-only HDF5 behavior.

Add explicit read-only access while preserving update mode by default.
@OutisLi OutisLi requested a review from njzjz July 12, 2026 09:38
@OutisLi OutisLi marked this pull request as ready for review July 12, 2026 09:38
Copilot AI review requested due to automatic review settings July 12, 2026 09:38
@dosubot dosubot Bot added the enhancement label Jul 12, 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 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Training now supports stat_file_mode values of update and read. PT rank 0 prepares the statistics cache accordingly, read-only paths reject writes, required cache entries are validated, and configuration and behavior tests cover the new flow.

Changes

Statistics cache mode handling

Layer / File(s) Summary
Statistics cache mode configuration
deepmd/utils/argcheck.py
Documents and validates stat_file_mode, defaults it to update, and requires stat_file for read mode.
Rank-aware cache preparation
deepmd/pt/entrypoints/main.py, examples/water/dpa4/input.json
Prepares statistics paths in read or update mode for rank 0, leaves nonzero ranks without a cache path, and adds the explicit update mode to the example.
Read-only path enforcement
deepmd/utils/path.py, source/tests/common/test_path.py
Blocks dataset writes and group creation on read-only HDF5 paths and tests the guards.
Statistics completeness validation
deepmd/dpmodel/utils/stat.py, deepmd/dpmodel/fitting/general_fitting.py, deepmd/pt/model/atomic_model/sezm_atomic_model.py, deepmd/pt/model/task/fitting.py, deepmd/pt/utils/stat.py
Requires expected statistics entries in read-only caches before restoration or fitting-stat computation.
Cache mode behavior tests
source/tests/pt/test_stat_file_mode.py
Tests writable defaults, read-only loading, missing and incomplete caches, multiple readers, and configuration validation.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TrainingConfig
  participant PTEntrypoint
  participant StatisticsCache
  participant StatisticsValidation
  participant HDF5
  TrainingConfig->>PTEntrypoint: provide stat_file and stat_file_mode
  PTEntrypoint->>StatisticsCache: prepare cache on rank 0
  StatisticsCache->>HDF5: open in read or update mode
  HDF5-->>StatisticsCache: return cache path
  StatisticsCache->>StatisticsValidation: require expected stat items
  StatisticsValidation-->>StatisticsCache: restore entries or raise missing-item error
Loading

Suggested labels: new feature

Suggested reviewers: iProzd, wanghan-iapcm, njzjz

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: enabling concurrent stat cache reads via the new PT read-only cache mode.
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.
✨ 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.

🧹 Nitpick comments (1)
source/tests/pt/test_stat_file_mode.py (1)

85-97: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding tests for _prepare_stat_file_path edge cases.

The tests cover the main scenarios well. Two edge cases in _prepare_stat_file_path that lack direct test coverage:

  1. Invalid stat_file_mode (lines 130-134 in main.py) — raises ValueError with a descriptive message
  2. stat_file=None with stat_file_mode="read" (lines 135-138 in main.py) — raises ValueError

These are caught upstream by argcheck.py validation, so the risk is low, but direct unit tests would protect against regressions if the function is called from new call sites.

🤖 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/test_stat_file_mode.py` around lines 85 - 97, Extend
test_stat_file_mode_configuration_validation with direct unit coverage for
_prepare_stat_file_path: assert invalid stat_file_mode raises ValueError with a
descriptive message, and assert stat_file=None with stat_file_mode="read" also
raises ValueError. Use the existing configuration/test fixtures and preserve the
current normalization assertions.
🤖 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 `@source/tests/pt/test_stat_file_mode.py`:
- Around line 85-97: Extend test_stat_file_mode_configuration_validation with
direct unit coverage for _prepare_stat_file_path: assert invalid stat_file_mode
raises ValueError with a descriptive message, and assert stat_file=None with
stat_file_mode="read" also raises ValueError. Use the existing
configuration/test fixtures and preserve the current normalization assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9de43e18-1401-4328-97ca-38177d11aaaa

📥 Commits

Reviewing files that changed from the base of the PR and between 98c3ab0 and c95b4d6.

📒 Files selected for processing (5)
  • deepmd/pt/entrypoints/main.py
  • deepmd/utils/argcheck.py
  • deepmd/utils/path.py
  • examples/water/dpa4/input.json
  • source/tests/pt/test_stat_file_mode.py

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

Opening a completed HDF5 statistics cache with mode r is the right direction, but the current implementation does not yet provide the documented load-only semantics.

Cache completeness depends on model-specific type-map suffixes, descriptor hashes, and required statistic keys, so checking only the top-level path in the entrypoint cannot establish that the cache is complete. I recommend making the statistics-loading layer distinguish these cases explicitly: load an existing item; compute and save a missing item only when the path is writable; and fail immediately with the missing statistic name when the path is read-only. This avoids sampling data before an eventual generic write error.

The cache-opening helper is also infrastructure rather than entrypoint logic. A focused module such as deepmd/utils/stat_file.py would keep creation/opening policy separate from main.py, while the generic read-only guards should remain in deepmd/utils/path.py and be covered in source/tests/common/test_path.py.

The CodeRabbit edge-test suggestion is reasonable but secondary. In particular, its statement that both cases are caught upstream is not correct for stat_file_mode="read" without stat_file.

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

Comment thread deepmd/pt/entrypoints/main.py
Comment thread deepmd/utils/argcheck.py
Comment thread source/tests/pt/test_stat_file_mode.py
@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.57%. Comparing base (98c3ab0) to head (c95b4d6).

Files with missing lines Patch % Lines
deepmd/pt/entrypoints/main.py 89.47% 2 Missing ⚠️
deepmd/utils/path.py 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5773      +/-   ##
==========================================
- Coverage   79.70%   79.57%   -0.14%     
==========================================
  Files        1020     1020              
  Lines      116359   116376      +17     
  Branches     4305     4303       -2     
==========================================
- Hits        92742    92603     -139     
- Misses      22076    22228     +152     
- Partials     1541     1545       +4     

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

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

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/stat.py (1)

91-103: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Make observed_type optional in read-only restores

_collect_and_set_observed_type skips _save_observed_type_to_file whenever preset_observed_type is provided, so caches created through that path can legitimately lack observed_type. In read mode, the unconditional _require_stat_file_items(..., ["observed_type"]) turns that into a hard FileNotFoundError even though the rest of the cache is usable. Relax this guard or fall back to recomputing when the entry is missing.

🤖 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/dpmodel/utils/stat.py` around lines 91 - 103, The read-only restore
path should tolerate caches without an observed_type entry. Update
_restore_observed_type_from_file to avoid unconditionally requiring
observed_type, return the stored values when the file exists, and return None
when it is absent so callers can recompute them.
🤖 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.

Outside diff comments:
In `@deepmd/dpmodel/utils/stat.py`:
- Around line 91-103: The read-only restore path should tolerate caches without
an observed_type entry. Update _restore_observed_type_from_file to avoid
unconditionally requiring observed_type, return the stored values when the file
exists, and return None when it is absent so callers can recompute them.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 96803061-6577-4f51-9f78-1e6cc4e48250

📥 Commits

Reviewing files that changed from the base of the PR and between c95b4d6 and 6864259.

📒 Files selected for processing (8)
  • deepmd/dpmodel/fitting/general_fitting.py
  • deepmd/dpmodel/utils/stat.py
  • deepmd/pt/model/atomic_model/sezm_atomic_model.py
  • deepmd/pt/model/task/fitting.py
  • deepmd/pt/utils/stat.py
  • deepmd/utils/argcheck.py
  • source/tests/common/test_path.py
  • source/tests/pt/test_stat_file_mode.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • deepmd/utils/argcheck.py

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