Skip to content

deprecate(ModelOutput.quantity): mark quantity field as deprecated#199

Open
HaoZeke wants to merge 1 commit intometatensor:mainfrom
HaoZeke:morfixes
Open

deprecate(ModelOutput.quantity): mark quantity field as deprecated#199
HaoZeke wants to merge 1 commit intometatensor:mainfrom
HaoZeke:morfixes

Conversation

@HaoZeke
Copy link
Copy Markdown
Member

@HaoZeke HaoZeke commented Apr 3, 2026

The quantity field is no longer required for unit conversion since the unit parser determines dimensions from the expression itself.

Changes:

  • Add deprecated documentation to C++ header
  • Add TORCH_WARN in C++ setter when quantity is non-empty
  • Add DeprecationWarning in Python when quantity validation runs
  • Update documentation with deprecation notice
  • Add deprecation entries to CHANGELOG

Contributor (creator of pull-request) checklist

  • Tests updated (for new features and bugfixes)?
  • Documentation updated (for new features)?
  • Issue referenced (for PRs that solve an issue)?

Reviewer checklist

  • CHANGELOG updated with public API or any other important changes?

@HaoZeke HaoZeke force-pushed the morfixes branch 3 times, most recently from 7b73a2a to 409b32c Compare April 5, 2026 00:50
@HaoZeke HaoZeke requested a review from Luthaf April 5, 2026 01:06
Comment thread metatomic-torch/include/metatomic/torch/model.hpp
Comment thread metatomic-torch/src/model.cpp Outdated
Comment thread python/metatomic_ase/tests/conftest.py Outdated
yield
captured = capfd.readouterr()
# the code should not print anything to stdout or stderr
# except for expected deprecation warnings
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These should be explicitly caught at the place where they are emitted in the test, by using the capfd fixture in the tests. I'm doing this in a couple of place already

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I really prefer this, it's much cleaner.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The point of checking warnings explicitly is similar to checking for exceptions. IMO it is not enough to check that "an exception has been thrown at some point", we want to make sure that the exception/warning we expect is produced exactly by the one line of code we expect to throw/emit it

Comment thread python/metatomic_torch/metatomic/torch/model.py Outdated
yield
captured = capfd.readouterr()
# the code should not print anything to stdout or stderr
# except for expected deprecation warnings
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

yield
captured = capfd.readouterr()
# the code should not print anything to stdout or stderr
# except for expected deprecation warnings
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

Comment on lines +50 to +53
# consume the once-per-process quantity deprecation warning from C++
captured = capfd.readouterr()
if captured.err:
assert "ModelOutput.quantity is deprecated" in captured.err
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can change the code in the test LJ to remove the need to catch this warning

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you do it over there, then we merge and use the new version here directly, instead of needing to update the code twice? Since we always pin lj-test with a specific commit, there should be no downstream issues doing this.

…-based unit conversion

The quantity field on ModelOutput is no longer required: the unit
expression parser determines dimensions directly, so unit conversion
no longer needs the quantity hint.

C++ (metatomic-torch)
- Mark `quantity()` getter and `set_quantity()` setter with
  `[[deprecated]]` so callers get a compile-time warning.
- In `set_quantity`, emit `TORCH_WARN_DEPRECATION` when a non-empty
  quantity is provided so JSON-deserialized models with `quantity` set
  surface the deprecation at runtime.

Python (metatomic-torch)
- Drop the quantity-vs-quantity gating and mismatch check in
  `model.py`; gate unit conversion on `unit` being non-empty instead.
  The unit parser already validates dimensional consistency.
- Add a `.. deprecated::` block to the `quantity` property docstring.

Tests / packaging
- conftest.py for all three subpackages: regex-strip the C++
  `TORCH_WARN_DEPRECATION` line from stderr in the autouse
  fail-on-output fixture, tolerating both Torch 2.3 (`[W model.cpp:N]`)
  and Torch 2.11+ (`[W<MMDD> HH:MM:SS.fractZ model.cpp:N]`) prefixes.
  Any other unexpected stderr still fails the test.
- `pyproject.toml` filterwarnings: ignore the matching Python
  `DeprecationWarning` so tests that exercise the field directly do
  not blow up under `-W error`.
- Update tests/examples that constructed `ModelOutput(quantity=...)`
  to drop the parameter where the test is not specifically about
  quantity validation.
- Update C++ models.cpp test to allow the deprecation warning.

Changelog: add a Deprecated entry for `ModelOutput.quantity`.
@HaoZeke HaoZeke requested a review from Luthaf April 16, 2026 12:06
HaoZeke added a commit that referenced this pull request Apr 17, 2026
…nd migrate call sites

Pol's fca4e05 kept the existing `TORCH_WARN_DEPRECATION` in
`set_per_atom` / `get_per_atom` intentionally: the new `sample_kind`
API is preferred and `per_atom` is the deprecated shim. This commit
mirrors the conftest/filterwarnings pattern the morfixes branch uses
for `ModelOutput.quantity`, applied only to `per_atom` (no overlap
with #199 -- this PR does not depend on morfixes).

Tests / packaging
- `tests/conftest.py` in all three subpackages: regex-strip the C++
  `TORCH_WARN_DEPRECATION` line for `per_atom` from stderr in the
  autouse `fail_test_with_output` fixture. The regex tolerates both
  Torch 2.3 (`[W model.cpp:N]`) and Torch 2.11+
  (`[W<MMDD> HH:MM:SS.fractZ model.cpp:N]`) prefixes. Any other
  unexpected stderr still fails the test.
- `pyproject.toml` in all three subpackages: ignore the matching
  Python `DeprecationWarning` so tests exercising the field directly
  do not blow up under `-W error`.
- `tests/outputs.py`: drop the two `assert message in captured.err`
  sections from `test_sample_kind`. On Torch 2.3 the C++ warning
  lands on stderr directly and the conftest regex scrubs it; on
  Torch 2.11 `PyErr_WarnEx` + the filterwarnings ignore leaves
  stderr empty. Asserting a specific stderr shape mid-test was
  torch-version-brittle. The `pytest.warns(match=...)` guards remain,
  so the shim is still verified. Drop the now-unused `capfd`
  parameter.

Internal call site migration
- `metatomic_torch/metatomic/torch/heat_flux.py`: the four
  `ModelOutput(..., per_atom=...)` call sites for masses/velocities/
  energies/heat_flux output all use `sample_kind="atom"/"system"`
  now, so the wrapper does not emit warnings from its own
  construction path.
- `metatomic_torch/metatomic/torch/model.py`: the dedup check in
  `_get_requested_inputs` compares `sample_kind` instead of reading
  the deprecated `per_atom` property.
- `metatomic_torch/tests/heat_flux.py`, `metatomic_ase/tests/heat_flux.py`,
  `metatomic_ase/tests/calculator.py::test_inputs_different_units`:
  migrate all `ModelOutput(..., per_atom=...)` to `sample_kind`.
HaoZeke added a commit that referenced this pull request Apr 17, 2026
My earlier switch to `HaoZeke/lj-test@f56f6b4` broke every test that
computes an energy via the reference LJ model: the fork drops
`quantity="energy"` from every `ModelOutput(...)` (forward-looking for
the morfixes #199 `quantity` deprecation), which causes
`AtomisticModel.forward()` to hit the early `continue` in

    if declared.quantity == "" or requested.quantity == "":
        continue

and skip the `unit_conversion_factor(declared.unit, requested.unit)`
step that the engine needs when asking for energy in `"ev"` while the
model declares `"eV"`. Downstream ASE tests see ~100x-wrong energies.

`metatensor/lj-test@eea52c6` is the existing upstream sample_kind
branch commit: it already migrates every `ModelOutput(per_atom=...)`
to `ModelOutput(sample_kind=...)` and every `outputs[...].per_atom`
read to `outputs[...].sample_kind == "atom"` so the runtime
deprecation path is not hit, but it keeps `quantity=...` intact so
unit conversion still runs. That is the right pin for this PR's
scope (per_atom only, no quantity overlap).

Both `install_lj_tests` and the inline `pip install` in the
`torch-tests` env are bumped to `eea52c6`. Bump again once that
branch lands on lj-test main and gets a stable SHA.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants