From 62ba7487e85e60e22c3293d5559d997bfe0a338b Mon Sep 17 00:00:00 2001 From: Corey Adams <6619961+coreyjadams@users.noreply.github.com> Date: Thu, 17 Sep 2026 08:54:43 -0500 Subject: [PATCH 1/5] Remove physicsnemo compatibility layer from v2.0 refactor, now that we are in v2.3 --- .importlinter | 3 - CHANGELOG.md | 6 + physicsnemo/__init__.py | 17 -- physicsnemo/compat/__init__.py | 227 ------------------ .../references/RECIPES.md | 4 +- test/compat/__init__.py | 15 -- test/compat/test_compat.py | 123 ---------- v2.0-MIGRATION-GUIDE.md | 28 +-- 8 files changed, 12 insertions(+), 411 deletions(-) delete mode 100644 physicsnemo/compat/__init__.py delete mode 100644 test/compat/__init__.py delete mode 100644 test/compat/test_compat.py diff --git a/.importlinter b/.importlinter index 853f6d1cdc..3ae21a46fe 100644 --- a/.importlinter +++ b/.importlinter @@ -9,14 +9,11 @@ contract_types = name = Prevent Upward Imports in the PhysicsNemo Structure type = layers exhaustive = True -ignore_imports = - physicsnemo -> physicsnemo.compat exhaustive_ignores = conftest containers= physicsnemo layers = - compat experimental deploy | active_learning | diffusion | sym models : datapipes : metrics : domain_parallel : optim diff --git a/CHANGELOG.md b/CHANGELOG.md index 56497067bd..c251745d0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed +- Removes the opt-in `physicsnemo.compat` import-alias layer and the + `PHYSICSNEMO_ENABLE_COMPAT` environment variable. The layer mapped pre-v2.0 + module paths onto their v2.0 locations; three minor releases later, callers + should import from the current paths listed in `v2.0-MIGRATION-GUIDE.md`. + Checkpoint loading is unaffected. + ### Fixed - Normalizes cell, point, transformed, and partition-cluster mesh normals diff --git a/physicsnemo/__init__.py b/physicsnemo/__init__.py index 59caf4fd1b..e0740e7c26 100644 --- a/physicsnemo/__init__.py +++ b/physicsnemo/__init__.py @@ -14,8 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os - # This is to ensure warp is quiet at startup: import warp as wp @@ -25,18 +23,3 @@ wp.config.log_level = wp.LOG_WARNING __version__ = "2.3.0a0" - - -# Backwards-compatibility is opt-in. Enable with env var or via enable_compat(). -if os.getenv("PHYSICSNEMO_ENABLE_COMPAT") in { - "1", - "true", - "True", - "YES", - "yes", - "on", - "ON", -}: - from .compat import install as _compat_install - - _compat_install() diff --git a/physicsnemo/compat/__init__.py b/physicsnemo/compat/__init__.py deleted file mode 100644 index eaf1769eba..0000000000 --- a/physicsnemo/compat/__init__.py +++ /dev/null @@ -1,227 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES. -# SPDX-FileCopyrightText: All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -This file is meant to provide a compatibility layer for physicsnemo v1 - -You can do -``` ->>> import physicsnemo.compat as physicsnemo ->>> # All previous paths should work. - -``` -""" - -import importlib -import sys -import types -import warnings - -COMPAT_MAP = { - "physicsnemo.utils.filesystem": "physicsnemo.core.filesystem", - "physicsnemo.utils.version_check": "physicsnemo.core.version_check", - "physicsnemo.models.meta": "physicsnemo.core.meta", - "physicsnemo.models.module": "physicsnemo.core.module", - "physicsnemo.utils.neighbors": "physicsnemo.nn.functional", - "physicsnemo.utils.sdf": "physicsnemo.nn.functional.geometry.sdf", - "physicsnemo.models.layers": "physicsnemo.nn", - "physicsnemo.models.layers.activations": "physicsnemo.nn.module.activations", - "physicsnemo.models.layers.attention_layers": "physicsnemo.nn.module.attention_layers", - "physicsnemo.models.layers.ball_query": "physicsnemo.nn.module.ball_query", - "physicsnemo.models.layers.conv_layers": "physicsnemo.nn.module.conv_layers", - "physicsnemo.models.layers.dgm_layers": "physicsnemo.nn.module.dgm_layers", - "physicsnemo.models.layers.drop": "physicsnemo.nn.module.drop", - "physicsnemo.models.layers.fft": "physicsnemo.nn.module.fft", - "physicsnemo.models.layers.fourier_layers": "physicsnemo.nn.module.fourier_layers", - "physicsnemo.models.layers.fully_connected_layers": "physicsnemo.nn.module.fully_connected_layers", - "physicsnemo.models.layers.fused_silu": "physicsnemo.nn.module.fused_silu", - "physicsnemo.models.layers.interpolation": "physicsnemo.nn.functional.interpolation", - "physicsnemo.models.layers.kan_layers": "physicsnemo.nn.module.kan_layers", - "physicsnemo.models.layers.mlp_layers": "physicsnemo.nn.module.mlp_layers", - "physicsnemo.models.layers.resample_layers": "physicsnemo.nn.module.resample_layers", - "physicsnemo.models.layers.siren_layers": "physicsnemo.nn.module.siren_layers", - "physicsnemo.models.layers.spectral_layers": "physicsnemo.nn.module.spectral_layers", - "physicsnemo.models.layers.transformer_decoder": "physicsnemo.nn.module.transformer_decoder", - "physicsnemo.models.layers.transformer_layers": "physicsnemo.nn.module.transformer_layers", - "physicsnemo.models.layers.weight_fact": "physicsnemo.nn.module.weight_fact", - "physicsnemo.models.layers.weight_norm": "physicsnemo.nn.module.weight_norm", - "physicsnemo.utils.graphcast": "physicsnemo.models.graphcast.utils", - "physicsnemo.utils.diffusion": "physicsnemo.diffusion.utils", - "physicsnemo.models.diffusion.corrdiff_utils": "physicsnemo.diffusion.samplers", - "physicsnemo.metrics.diffusion": "physicsnemo.diffusion.metrics", - "physicsnemo.utils.patching": "physicsnemo.diffusion.multi_diffusion.patching", - "physicsnemo.utils.domino": "physicsnemo.models.domino.utils", - "physicsnemo.launch.utils.checkpoint": "physicsnemo.utils.checkpoint", - "physicsnemo.launch.logging": "physicsnemo.utils.logging", - "physicsnemo.distributed.shard_tensor": "physicsnemo.domain_parallel.shard_tensor", -} - -OBJECT_COMPAT_MAP = { - # Diffusion layers - "physicsnemo.models.diffusion.AttentionOp": "physicsnemo.nn.AttentionOp", - "physicsnemo.models.diffusion.layers.Attention": "physicsnemo.nn.UNetAttention", - "physicsnemo.models.diffusion.Conv2D": "physicsnemo.nn.Conv2d", - "physicsnemo.models.diffusion.FourierEmbedding": "physicsnemo.nn.FourierEmbedding", - "physicsnemo.models.diffusion.GroupNorm": "physicsnemo.nn.GroupNorm", - "physicsnemo.models.diffusion.get_group_norm": "physicsnemo.nn.get_group_norm", - "physicsnemo.models.diffusion.Linear": "physicsnemo.nn.Linear", - "physicsnemo.models.diffusion.PositionalEmbedding": "physicsnemo.nn.PositionalEmbedding", - "physicsnemo.models.diffusion.UNetBlock": "physicsnemo.nn.UNetBlock", - # Diffusion UNets - "physicsnemo.models.diffusion.SongUNet": "physicsnemo.models.diffusion_unets.SongUNet", - "physicsnemo.models.diffusion.SongUNetPosEmbd": "physicsnemo.models.diffusion_unets.SongUNetPosEmbd", - "physicsnemo.models.diffusion.SongUNetPosLtEmbd": "physicsnemo.models.diffusion_unets.SongUNetPosLtEmbd", - "physicsnemo.models.diffusion.DhariwalUNet": "physicsnemo.models.diffusion_unets.DhariwalUNet", - "physicsnemo.models.diffusion.UNet": "physicsnemo.models.diffusion_unets.UNet", - "physicsnemo.models.diffusion.StormCastUNet": "physicsnemo.models.diffusion_unets.StormCastUNet", - # Diffusion Preconditioners - "physicsnemo.models.diffusion.EDMPrecond": "physicsnemo.diffusion.preconditioners.EDMPrecond", - "physicsnemo.models.diffusion.EDMPrecondSuperResolution": "physicsnemo.diffusion.preconditioners.EDMPrecondSuperResolution", - "physicsnemo.models.diffusion.EDMPrecondSR": "physicsnemo.diffusion.preconditioners.EDMPrecondSR", - "physicsnemo.models.diffusion.VEPrecond": "physicsnemo.diffusion.preconditioners.VEPrecond", - "physicsnemo.models.diffusion.VPPrecond": "physicsnemo.diffusion.preconditioners.VPPrecond", - "physicsnemo.models.diffusion.iDDPMPrecond": "physicsnemo.diffusion.preconditioners.iDDPMPrecond", - "physicsnemo.models.diffusion.VEPrecond_dfsr_cond": "physicsnemo.diffusion.preconditioners.VEPrecond_dfsr_cond", - "physicsnemo.models.diffusion.VEPrecond_dfsr": "physicsnemo.diffusion.preconditioners.VEPrecond_dfsr", -} - - -def _ensure_parent_packages(module_name: str) -> None: - """Ensure every parent package of ``module_name`` exists in sys.modules. - - Only the parent chain is created; the final segment (the module itself) is - not. This allows later code to assign that final name (e.g. to a real - module alias or a placeholder). - - For each missing parent, a placeholder ``ModuleType`` is created, stored in - ``sys.modules`` under that parent's full name, and attached as an - attribute on its own parent (so ``import physicsnemo.models`` can resolve - ``physicsnemo.models`` both via sys.modules and as ``physicsnemo.models``). - The root (first segment) is assumed to already exist (e.g. ``physicsnemo`` - is already loaded before compat runs). - - Example: for ``module_name="physicsnemo.models.diffusion"``, this ensures - ``physicsnemo`` and ``physicsnemo.models`` exist as placeholders if missing. - It does not create ``physicsnemo.models.diffusion``. So - ``from physicsnemo.models.diffusion import X`` still requires something else - to put ``physicsnemo.models.diffusion`` in sys.modules. (see below) - - If ``module_name`` has only one or two segments (e.g. ``"physicsnemo"`` or - ``"physicsnemo.models"``), the loop over parent packages runs over no - indices, so nothing is created; that is intentional (the "module" is then - the top-level or second-level name, and no intermediate chain is needed). - """ - parts = module_name.split(".") - for i in range(1, len(parts) - 1): - parent_name = ".".join(parts[: i + 1]) - if parent_name in sys.modules: - continue - # Prefer loading the real parent module/package when it exists. - try: - importlib.import_module(parent_name) - continue - except ImportError: - pass - placeholder = types.ModuleType(parts[i]) - sys.modules[parent_name] = placeholder - grandparent_name = ".".join(parts[:i]) - grandparent = sys.modules.get(grandparent_name) - if grandparent is not None: - setattr(grandparent, parts[i], placeholder) - - -def _ensure_module_exists(module_name: str) -> types.ModuleType: - """Ensure ``module_name`` exists in sys.modules, creating a placeholder if needed. - - If the module is already loaded, it is returned. Otherwise the parent - package chain is ensured (via _ensure_parent_packages), then a placeholder - module for ``module_name`` is created, registered in sys.modules, and - attached to its parent, so the full path is importable. - - Example: for ``module_name="physicsnemo.models.diffusion"``, this guarantees - ``physicsnemo.models.diffusion`` exists (creating a placeholder when the - module was removed). Callers can then set attributes on it (e.g. compat - aliases) so ``from physicsnemo.models.diffusion import UNetBlock`` works. - """ - if module_name in sys.modules: - return sys.modules[module_name] - _ensure_parent_packages(module_name) - parent_name, child = module_name.rsplit(".", 1) - parent_mod = sys.modules[parent_name] - placeholder = types.ModuleType(child) - sys.modules[module_name] = placeholder - setattr(parent_mod, child, placeholder) - return placeholder - - -def install(): - """Install backward-compatibility shims.""" - for old_name, new_name in COMPAT_MAP.items(): - try: - new_mod = importlib.import_module(new_name) - except ImportError: - warnings.warn( - f"Failed to import new module '{new_name}' for compat alias '{old_name}'" - ) - continue - - # Register module alias - sys.modules[old_name] = new_mod - - # Ensure removed parent packages exist so "from pkg.subpkg import name" works - _ensure_parent_packages(old_name) - - # Attach the alias on the parent package - try: - parent_name, child = old_name.rsplit(".", 1) - parent_mod = sys.modules[parent_name] - setattr(parent_mod, child, new_mod) - except Exception: - warnings.warn( - f"Failed to attach '{old_name}' onto its parent for compat alias; using sys.modules only" - ) - - warnings.warn( - f"[compat] {old_name} is moved; use {new_name} instead", - DeprecationWarning, - ) - - for old_path, new_path in OBJECT_COMPAT_MAP.items(): - old_module_name, old_obj_name = old_path.rsplit(".", 1) - new_module_name, new_obj_name = new_path.rsplit(".", 1) - - try: - new_mod = importlib.import_module(new_module_name) - new_obj = getattr(new_mod, new_obj_name) - except (ImportError, AttributeError): - warnings.warn( - f"Failed to import '{new_path}' for compat alias '{old_path}'" - ) - continue - - try: - old_mod = _ensure_module_exists(old_module_name) - setattr(old_mod, old_obj_name, new_obj) - except Exception: - warnings.warn( - f"Failed to attach '{old_path}' onto its parent " - "for compat alias; using sys.modules only" - ) - - warnings.warn( - f"[compat] {old_path} is moved; use {new_path} instead", - DeprecationWarning, - ) diff --git a/skills/physicsnemo-discover/references/RECIPES.md b/skills/physicsnemo-discover/references/RECIPES.md index 3ec91a1564..9a7646e711 100644 --- a/skills/physicsnemo-discover/references/RECIPES.md +++ b/skills/physicsnemo-discover/references/RECIPES.md @@ -156,8 +156,8 @@ Grep -n "^class " physicsnemo/ --type py # 7b. Search by function name Grep -n "^def " physicsnemo/ --type py -# 7c. If not found where expected — check compat layer for renames -Read physicsnemo/compat/__init__.py +# 7c. If not found where expected — check the rename tables for moved paths +Grep -n "" v2.0-MIGRATION-GUIDE.md CHANGELOG.md ``` If a name isn't found anywhere, it may have been renamed. Do not emit it. diff --git a/test/compat/__init__.py b/test/compat/__init__.py deleted file mode 100644 index af85283aa4..0000000000 --- a/test/compat/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES. -# SPDX-FileCopyrightText: All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. diff --git a/test/compat/test_compat.py b/test/compat/test_compat.py deleted file mode 100644 index 9727a7031a..0000000000 --- a/test/compat/test_compat.py +++ /dev/null @@ -1,123 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES. -# SPDX-FileCopyrightText: All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import importlib -import re -import sys -import warnings - -import pytest - -from physicsnemo.compat import COMPAT_MAP, install - -# Old paths whose new target may be missing in minimal installs (optional deps). -# If install() skips these, resolution/parent tests skip; warning tests allow them. -KNOWN_OPTIONAL_OLD_NAMES = frozenset( - { - "physicsnemo.utils.graphcast", - "physicsnemo.utils.diffusion", - "physicsnemo.utils.domino", - "physicsnemo.launch.utils.checkpoint", - "physicsnemo.launch.logging", - } -) - - -@pytest.fixture(scope="module") -def compat_installed(): - """Run compat.install() once per test module; suppress deprecation output.""" - with warnings.catch_warnings(): - warnings.filterwarnings( - "ignore", - category=DeprecationWarning, - module="physicsnemo.compat", - ) - install() - - -@pytest.mark.parametrize( - "old_name,new_name", - list(COMPAT_MAP.items()), - ids=list(COMPAT_MAP.keys()), -) -def test_compat_install_old_path_resolves_to_new_module( - compat_installed, old_name, new_name -): - """For each COMPAT_MAP entry, old-name import returns the same module as new-name.""" - if old_name not in sys.modules: - pytest.skip( - f"Compat alias {old_name!r} not registered (new module may have optional deps)" - ) - old_mod = importlib.import_module(old_name) - new_mod = importlib.import_module(new_name) - assert old_mod is new_mod - - -@pytest.mark.parametrize( - "old_name,new_name", - list(COMPAT_MAP.items()), - ids=list(COMPAT_MAP.keys()), -) -def test_compat_parent_package_has_old_submodule_attribute( - compat_installed, old_name, new_name -): - """Old paths are reachable via parent package attribute (from pkg import sub).""" - if old_name not in sys.modules: - pytest.skip( - f"Compat alias {old_name!r} not registered (new module may have optional deps)" - ) - parent_name, child = old_name.rsplit(".", 1) - try: - parent_mod = importlib.import_module(parent_name) - except ModuleNotFoundError: - pytest.skip( - f"Parent package {parent_name!r} does not exist (e.g. removed package)" - ) - new_mod = importlib.import_module(new_name) - assert getattr(parent_mod, child) is new_mod - - -def test_compat_install_no_failed_import_warnings(): - """install() does not emit 'Failed to import new module' unless from known optional targets.""" - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", UserWarning) - install() - failed = [ - x - for x in w - if x.category is UserWarning and "Failed to import new module" in str(x.message) - ] - # Message format: "Failed to import new module '...' for compat alias 'old_name'" - alias_re = re.compile(r"for compat alias '([^']+)'") - for rec in failed: - match = alias_re.search(str(rec.message)) - assert match, f"Could not parse alias from: {rec.message}" - old_name = match.group(1) - assert old_name in KNOWN_OPTIONAL_OLD_NAMES, ( - f"Unexpected failed import for {old_name!r}; add to KNOWN_OPTIONAL_OLD_NAMES if optional" - ) - - -def test_compat_map_structure(): - """COMPAT_MAP has valid keys/values and is non-empty.""" - assert len(COMPAT_MAP) > 0 - for key, value in COMPAT_MAP.items(): - assert isinstance(key, str) and len(key) > 0 - assert isinstance(value, str) and len(value) > 0 - assert "." in key, f"Key should be a module path: {key!r}" - assert len(COMPAT_MAP) == len(set(COMPAT_MAP.keys())), ( - "COMPAT_MAP keys must be unique" - ) diff --git a/v2.0-MIGRATION-GUIDE.md b/v2.0-MIGRATION-GUIDE.md index 46f4441963..6f1d704a24 100644 --- a/v2.0-MIGRATION-GUIDE.md +++ b/v2.0-MIGRATION-GUIDE.md @@ -46,30 +46,10 @@ imports. For most uses, the key changes are: ## Compatibility Layer -Some of physicsnemo v2.0 is new functionality, but for components we have moved -or relocated for installation and dependency management, we have introduced -`physicsnemo.compat`. As a thin compatibility layer, `physicsnemo.compat` -attaches a mapping to the `sys.modules` path so old import locations can still -work. For example, `physicsnemo.models.module` was moved to `physicsnemo.core` -in v2.0. With the compatibility layer enabled, `from physicsnemo.models import module` -will still work correctly (even though that import doesn't actually exist anymore). - -The goal of the compatibility layer is to make transistioning to physicsnemo v2.0 -easier. Where possible, if it's simple to update your import paths we recommend -that. If for some reason it is not as easy to update your code, the compatibility -layer can help. - -To use the compatibility layer, there are two options. First, you can set -the environment variable `PHYSICSNEMO_ENABLE_COMPAT` to `1` (or similar truth-y -values like `true`, `on`, etc.) and upon import the compatibility layer will be -enabled. To enable it manually, - -```python -from physicsnemo.compat import install -install() -``` - -should suffice. +PhysicsNeMo v2.0 through v2.2 shipped an opt-in `physicsnemo.compat` module that +aliased pre-v2.0 import paths onto their new locations. That layer was removed in +v2.3. Update import paths using the tables in this guide; the `PHYSICSNEMO_ENABLE_COMPAT` +environment variable no longer has any effect. ## New Packages From c9480865ab61d03aa10e094e53fe973fc912439b Mon Sep 17 00:00:00 2001 From: Corey Adams <6619961+coreyjadams@users.noreply.github.com> Date: Tue, 22 Sep 2026 13:29:10 -0500 Subject: [PATCH 2/5] Update migration guide and skills for discoverability --- .../references/RECIPES.md | 3 +- v2.0-MIGRATION-GUIDE.md | 76 ++++++++++++++++++- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/skills/physicsnemo-discover/references/RECIPES.md b/skills/physicsnemo-discover/references/RECIPES.md index 9a7646e711..7f20d35e61 100644 --- a/skills/physicsnemo-discover/references/RECIPES.md +++ b/skills/physicsnemo-discover/references/RECIPES.md @@ -157,7 +157,8 @@ Grep -n "^class " physicsnemo/ --type py Grep -n "^def " physicsnemo/ --type py # 7c. If not found where expected — check the rename tables for moved paths -Grep -n "" v2.0-MIGRATION-GUIDE.md CHANGELOG.md +# ( is the class or function name from 7a / 7b) +Grep -n "" v2.0-MIGRATION-GUIDE.md CHANGELOG.md ``` If a name isn't found anywhere, it may have been renamed. Do not emit it. diff --git a/v2.0-MIGRATION-GUIDE.md b/v2.0-MIGRATION-GUIDE.md index 6f1d704a24..9ffa15123e 100644 --- a/v2.0-MIGRATION-GUIDE.md +++ b/v2.0-MIGRATION-GUIDE.md @@ -48,8 +48,80 @@ imports. For most uses, the key changes are: PhysicsNeMo v2.0 through v2.2 shipped an opt-in `physicsnemo.compat` module that aliased pre-v2.0 import paths onto their new locations. That layer was removed in -v2.3. Update import paths using the tables in this guide; the `PHYSICSNEMO_ENABLE_COMPAT` -environment variable no longer has any effect. +v2.3, and the `PHYSICSNEMO_ENABLE_COMPAT` environment variable no longer has any +effect. The tables below list every alias it provided; update imports accordingly. + +### Moved modules + +Any name previously imported from the module on the left is now imported from the +module on the right. + +| Before (pre-v2.0) | After | +|---|---| +| `physicsnemo.distributed.shard_tensor` | `physicsnemo.domain_parallel.shard_tensor` | +| `physicsnemo.launch.logging` | `physicsnemo.utils.logging` | +| `physicsnemo.launch.utils.checkpoint` | `physicsnemo.utils.checkpoint` | +| `physicsnemo.metrics.diffusion` | `physicsnemo.diffusion.metrics` | +| `physicsnemo.models.diffusion.corrdiff_utils` | `physicsnemo.diffusion.samplers` | +| `physicsnemo.models.layers` | `physicsnemo.nn` | +| `physicsnemo.models.layers.activations` | `physicsnemo.nn.module.activations` | +| `physicsnemo.models.layers.attention_layers` | `physicsnemo.nn.module.attention_layers` | +| `physicsnemo.models.layers.ball_query` | `physicsnemo.nn.module.ball_query` | +| `physicsnemo.models.layers.conv_layers` | `physicsnemo.nn.module.conv_layers` | +| `physicsnemo.models.layers.dgm_layers` | `physicsnemo.nn.module.dgm_layers` | +| `physicsnemo.models.layers.drop` | `physicsnemo.nn.module.drop` | +| `physicsnemo.models.layers.fft` | `physicsnemo.nn.module.fft` | +| `physicsnemo.models.layers.fourier_layers` | `physicsnemo.nn.module.fourier_layers` | +| `physicsnemo.models.layers.fully_connected_layers` | `physicsnemo.nn.module.fully_connected_layers` | +| `physicsnemo.models.layers.fused_silu` | `physicsnemo.nn.module.fused_silu` | +| `physicsnemo.models.layers.interpolation` | `physicsnemo.nn.functional.interpolation` | +| `physicsnemo.models.layers.kan_layers` | `physicsnemo.nn.module.kan_layers` | +| `physicsnemo.models.layers.mlp_layers` | `physicsnemo.nn.module.mlp_layers` | +| `physicsnemo.models.layers.resample_layers` | `physicsnemo.nn.module.resample_layers` | +| `physicsnemo.models.layers.siren_layers` | `physicsnemo.nn.module.siren_layers` | +| `physicsnemo.models.layers.spectral_layers` | `physicsnemo.nn.module.spectral_layers` | +| `physicsnemo.models.layers.transformer_decoder` | `physicsnemo.nn.module.transformer_decoder` | +| `physicsnemo.models.layers.transformer_layers` | `physicsnemo.nn.module.transformer_layers` | +| `physicsnemo.models.layers.weight_fact` | `physicsnemo.nn.module.weight_fact` | +| `physicsnemo.models.layers.weight_norm` | `physicsnemo.nn.module.weight_norm` | +| `physicsnemo.models.meta` | `physicsnemo.core.meta` | +| `physicsnemo.models.module` | `physicsnemo.core.module` | +| `physicsnemo.utils.diffusion` | `physicsnemo.diffusion.utils` | +| `physicsnemo.utils.domino` | `physicsnemo.models.domino.utils` | +| `physicsnemo.utils.filesystem` | `physicsnemo.core.filesystem` | +| `physicsnemo.utils.graphcast` | `physicsnemo.models.graphcast.utils` | +| `physicsnemo.utils.neighbors` | `physicsnemo.nn.functional` | +| `physicsnemo.utils.patching` | `physicsnemo.diffusion.multi_diffusion.patching` | +| `physicsnemo.utils.sdf` | `physicsnemo.nn.functional.geometry.sdf` | +| `physicsnemo.utils.version_check` | `physicsnemo.core.version_check` | + +### Moved classes and functions + +| Before (pre-v2.0) | After | +|---|---| +| `physicsnemo.models.diffusion.AttentionOp` | `physicsnemo.nn.AttentionOp` | +| `physicsnemo.models.diffusion.Conv2D` | `physicsnemo.nn.Conv2d` | +| `physicsnemo.models.diffusion.DhariwalUNet` | `physicsnemo.models.diffusion_unets.DhariwalUNet` | +| `physicsnemo.models.diffusion.EDMPrecond` | `physicsnemo.diffusion.preconditioners.EDMPrecond` | +| `physicsnemo.models.diffusion.EDMPrecondSR` | `physicsnemo.diffusion.preconditioners.EDMPrecondSR` | +| `physicsnemo.models.diffusion.EDMPrecondSuperResolution` | `physicsnemo.diffusion.preconditioners.EDMPrecondSuperResolution` | +| `physicsnemo.models.diffusion.FourierEmbedding` | `physicsnemo.nn.FourierEmbedding` | +| `physicsnemo.models.diffusion.GroupNorm` | `physicsnemo.nn.GroupNorm` | +| `physicsnemo.models.diffusion.Linear` | `physicsnemo.nn.Linear` | +| `physicsnemo.models.diffusion.PositionalEmbedding` | `physicsnemo.nn.PositionalEmbedding` | +| `physicsnemo.models.diffusion.SongUNet` | `physicsnemo.models.diffusion_unets.SongUNet` | +| `physicsnemo.models.diffusion.SongUNetPosEmbd` | `physicsnemo.models.diffusion_unets.SongUNetPosEmbd` | +| `physicsnemo.models.diffusion.SongUNetPosLtEmbd` | `physicsnemo.models.diffusion_unets.SongUNetPosLtEmbd` | +| `physicsnemo.models.diffusion.StormCastUNet` | `physicsnemo.models.diffusion_unets.StormCastUNet` | +| `physicsnemo.models.diffusion.UNet` | `physicsnemo.models.diffusion_unets.UNet` | +| `physicsnemo.models.diffusion.UNetBlock` | `physicsnemo.nn.UNetBlock` | +| `physicsnemo.models.diffusion.VEPrecond` | `physicsnemo.diffusion.preconditioners.VEPrecond` | +| `physicsnemo.models.diffusion.VEPrecond_dfsr` | `physicsnemo.diffusion.preconditioners.VEPrecond_dfsr` | +| `physicsnemo.models.diffusion.VEPrecond_dfsr_cond` | `physicsnemo.diffusion.preconditioners.VEPrecond_dfsr_cond` | +| `physicsnemo.models.diffusion.VPPrecond` | `physicsnemo.diffusion.preconditioners.VPPrecond` | +| `physicsnemo.models.diffusion.get_group_norm` | `physicsnemo.nn.get_group_norm` | +| `physicsnemo.models.diffusion.iDDPMPrecond` | `physicsnemo.diffusion.preconditioners.iDDPMPrecond` | +| `physicsnemo.models.diffusion.layers.Attention` | `physicsnemo.nn.UNetAttention` | ## New Packages From 70a57d1cdcf9eac0d291e51017e7acb0be58eea2 Mon Sep 17 00:00:00 2001 From: Corey adams <6619961+coreyjadams@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:15:03 -0500 Subject: [PATCH 3/5] Update v2.0-MIGRATION-GUIDE.md Co-authored-by: megnvidia --- v2.0-MIGRATION-GUIDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2.0-MIGRATION-GUIDE.md b/v2.0-MIGRATION-GUIDE.md index 9ffa15123e..4ff5a25d32 100644 --- a/v2.0-MIGRATION-GUIDE.md +++ b/v2.0-MIGRATION-GUIDE.md @@ -95,7 +95,7 @@ module on the right. | `physicsnemo.utils.sdf` | `physicsnemo.nn.functional.geometry.sdf` | | `physicsnemo.utils.version_check` | `physicsnemo.core.version_check` | -### Moved classes and functions +### Moved Classes and Functions | Before (pre-v2.0) | After | |---|---| From 6d7ab8d7a33365201c86bcc64de5892994845435 Mon Sep 17 00:00:00 2001 From: Corey adams <6619961+coreyjadams@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:15:11 -0500 Subject: [PATCH 4/5] Update v2.0-MIGRATION-GUIDE.md Co-authored-by: megnvidia --- v2.0-MIGRATION-GUIDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2.0-MIGRATION-GUIDE.md b/v2.0-MIGRATION-GUIDE.md index 4ff5a25d32..283907672d 100644 --- a/v2.0-MIGRATION-GUIDE.md +++ b/v2.0-MIGRATION-GUIDE.md @@ -51,7 +51,7 @@ aliased pre-v2.0 import paths onto their new locations. That layer was removed i v2.3, and the `PHYSICSNEMO_ENABLE_COMPAT` environment variable no longer has any effect. The tables below list every alias it provided; update imports accordingly. -### Moved modules +### Moved Modules Any name previously imported from the module on the left is now imported from the module on the right. From cbd1e34853cbe6b3ecfe4ad6fce7d0a92c59a6c5 Mon Sep 17 00:00:00 2001 From: Corey adams <6619961+coreyjadams@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:15:20 -0500 Subject: [PATCH 5/5] Update skills/physicsnemo-discover/references/RECIPES.md Co-authored-by: megnvidia --- skills/physicsnemo-discover/references/RECIPES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/physicsnemo-discover/references/RECIPES.md b/skills/physicsnemo-discover/references/RECIPES.md index 7f20d35e61..a451f2bf0d 100644 --- a/skills/physicsnemo-discover/references/RECIPES.md +++ b/skills/physicsnemo-discover/references/RECIPES.md @@ -156,7 +156,7 @@ Grep -n "^class " physicsnemo/ --type py # 7b. Search by function name Grep -n "^def " physicsnemo/ --type py -# 7c. If not found where expected — check the rename tables for moved paths +# 7c. If not found where expected, review the rename tables for moved paths # ( is the class or function name from 7a / 7b) Grep -n "" v2.0-MIGRATION-GUIDE.md CHANGELOG.md ```