From 321f32b171f8ef0082a87de9d4b05b8b56f96ec6 Mon Sep 17 00:00:00 2001 From: manfredss Date: Mon, 29 Jun 2026 03:50:10 +0000 Subject: [PATCH 01/34] change for enable_compat --- paconvert/api_mapping.json | 63 +++++++-------------- paconvert/transformer/import_transformer.py | 17 ++++++ tests/apibase.py | 23 ++++++++ tests/confest.py | 42 ++++++++++++++ 4 files changed, 103 insertions(+), 42 deletions(-) create mode 100644 tests/confest.py diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 2b4e144f8..38385974e 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -3108,8 +3108,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.allclose": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.allclose" + "Matcher": "ChangePrefixMatcher" }, "torch.alpha_dropout": { "Matcher": "GenericMatcher", @@ -5158,8 +5157,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.equal": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.equal" + "Matcher": "ChangePrefixMatcher" }, "torch.erf": { "Matcher": "ChangePrefixMatcher" @@ -6531,8 +6529,7 @@ "min_input_args": 1 }, "torch.max": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.max" + "Matcher": "ChangePrefixMatcher" }, "torch.max_pool1d": { "Matcher": "ChangeAPIMatcher", @@ -6553,15 +6550,13 @@ "Matcher": "ChangePrefixMatcher" }, "torch.median": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.median" + "Matcher": "ChangePrefixMatcher" }, "torch.meshgrid": { "Matcher": "ChangePrefixMatcher" }, "torch.min": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.min" + "Matcher": "ChangePrefixMatcher" }, "torch.minimum": { "Matcher": "ChangePrefixMatcher" @@ -6685,8 +6680,7 @@ } }, "torch.nanmedian": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nanmedian" + "Matcher": "ChangePrefixMatcher" }, "torch.nanquantile": { "Matcher": "ChangePrefixMatcher" @@ -6777,16 +6771,13 @@ ] }, "torch.nn.AvgPool1d": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.AvgPool1d" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.AvgPool2d": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.AvgPool2d" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.AvgPool3d": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.AvgPool3d" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.BCELoss": { "Matcher": "SizeAverageMatcher", @@ -7362,8 +7353,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.nn.Linear": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.Linear" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.LocalResponseNorm": { "Matcher": "ChangePrefixMatcher" @@ -7628,8 +7618,7 @@ ] }, "torch.nn.MultiheadAttention": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.MultiheadAttention" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.NLLLoss": { "Matcher": "SizeAverageMatcher", @@ -7856,8 +7845,7 @@ "min_input_args": 0 }, "torch.nn.Softmax": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.Softmax" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.Softmax2d": { "Matcher": "GenericMatcher", @@ -8095,8 +8083,7 @@ } }, "torch.nn.Unfold": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.Unfold" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.Upsample": { "Matcher": "ChangePrefixMatcher" @@ -8691,8 +8678,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.nn.functional.linear": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.functional.linear" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.functional.local_response_norm": { "Matcher": "GenericMatcher", @@ -8710,8 +8696,7 @@ } }, "torch.nn.functional.log_softmax": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.functional.log_softmax" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.functional.logsigmoid": { "Matcher": "ChangePrefixMatcher" @@ -8889,8 +8874,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.nn.functional.pad": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.functional.pad" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.functional.pairwise_distance": { "Matcher": "ChangePrefixMatcher" @@ -9049,8 +9033,7 @@ "min_input_args": 2 }, "torch.nn.functional.softmax": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.functional.softmax" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.functional.softmin": { "Matcher": "FSoftMinMatcher", @@ -9167,8 +9150,7 @@ "min_input_args": 3 }, "torch.nn.functional.unfold": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.functional.unfold" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.functional.upsample": { "Matcher": "GenericMatcher", @@ -10433,8 +10415,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.seed": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.seed" + "Matcher": "ChangePrefixMatcher" }, "torch.select": { "Matcher": "SelectMatcher", @@ -10818,8 +10799,7 @@ "min_input_args": 2 }, "torch.sort": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.sort" + "Matcher": "ChangePrefixMatcher" }, "torch.sparse.FloatTensor": { "Matcher": "GenericMatcher", @@ -11222,8 +11202,7 @@ }, "torch.special.zeta": {}, "torch.split": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.split" + "Matcher": "ChangePrefixMatcher" }, "torch.sqrt": { "Matcher": "ChangePrefixMatcher" diff --git a/paconvert/transformer/import_transformer.py b/paconvert/transformer/import_transformer.py index 99a20840b..435b4fd4c 100644 --- a/paconvert/transformer/import_transformer.py +++ b/paconvert/transformer/import_transformer.py @@ -525,3 +525,20 @@ def visit_Module(self, node): (self.root, "body", 0), ast.parse(f"import {paddle_package}").body ) line_NO += 1 + + # Inject `paddle.enable_compat()` right after the imports so that + # prefix-only converted calls (torch.X -> paddle.X via ChangePrefixMatcher) + # resolve to the torch-aligned paddle.compat.* implementations at runtime + # `import paddle` is included explicitly (deduped if already added) so the + # call is valid even when torch was imported as a submodule alias + # (e.g. `import torch.nn as nn` -> `import paddle.nn as nn`) + if paddle_package_list: + log_info( + self.logger, + "add 'paddle.enable_compat()' after imports", + self.file_name, + ) + self.record_scope( + (self.root, "body", 0), + ast.parse("import paddle\npaddle.enable_compat()").body, + ) diff --git a/tests/apibase.py b/tests/apibase.py index a882e18d9..f9c06adc7 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -24,6 +24,27 @@ from paconvert.converter import Converter +def _ensure_paddle_compat_disabled(): + """Converted Paddle code now injects ``paddle.enable_compat()``, which installs + a global ``import torch`` -> Paddle proxy and aliases ``paddle.*`` to the + torch-aligned ``paddle.compat.*`` APIs. That global state must be OFF when the + torch *reference* snippet runs, otherwise its ``import torch`` would be proxied + to Paddle and the reference would no longer be real torch. No-op when Paddle + was never imported (compat cannot be active then), so the first reference run is + unaffected. + """ + if "paddle" not in sys.modules: + return + paddle = sys.modules["paddle"] + try: + from paddle.compat.proxy import TORCH_PROXY_FINDER + + while TORCH_PROXY_FINDER in sys.meta_path: + paddle.disable_compat() + except ImportError: + pass + + class APIBase(object): def __init__(self, pytorch_api) -> None: """ @@ -85,6 +106,7 @@ def run( ) assert paddle_code == expect_paddle_code, error_msg elif compared_tensor_names: + _ensure_paddle_compat_disabled() pytorch_ns = {} try: exec(pytorch_code, pytorch_ns) @@ -117,6 +139,7 @@ def run( except Exception as e: raise AssertionError(f"Unable to align results: {e}") else: + _ensure_paddle_compat_disabled() pytorch_ns = {} try: exec(pytorch_code, pytorch_ns) diff --git a/tests/confest.py b/tests/confest.py new file mode 100644 index 000000000..12a31e481 --- /dev/null +++ b/tests/confest.py @@ -0,0 +1,42 @@ +# Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved. +# +# 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 sys + +import pytest + + +@pytest.fixture(autouse=True) +def _reset_paddle_compat_mode(): + """Converted Paddle code node injects ``paddle.enable_compat()``, which flips + global state: it installs an ``import torch`` -> Paddle proxy adn aliases + ``paddle.*`` to the torch-aligned ``paddle.compat.*`` APIs. Disable it after + every test so it cannot leak into a later test (e.g., corrupt another test's) + real-torch reference run, or break tests that assume compat is off. + + Lazy and best-effort: a no-op when Paddle was never imported, so it does not + force a Paddle import (and thus does not change torch/paddle import ordering) + for tests that never touch Paddle + """ + yield + if "paddle" not in sys.modules: + return + paddle = sys.modules["paddle"] + try: + from paddle.compat.proxy import TORCH_PROXY_FINDER + + while TORCH_PROXY_FINDER in sys.meta_path: + paddle.disable_compat() + except Exception: + pass From 9bf7bfb10cd677166828f6531821dd258b069a00 Mon Sep 17 00:00:00 2001 From: manfredss Date: Mon, 29 Jun 2026 04:03:22 +0000 Subject: [PATCH 02/34] add two left api --- paconvert/api_mapping.json | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 38385974e..243a3a7e7 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -8976,8 +8976,7 @@ } }, "torch.nn.functional.scaled_dot_product_attention": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.functional.scaled_dot_product_attention" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.functional.selu": { "Matcher": "GenericMatcher", @@ -11505,16 +11504,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.unique": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.unique", - "min_input_args": 1, - "args_list": [ - "input", - "sorted", - "return_inverse", - "return_counts", - "dim" - ] + "Matcher": "ChangePrefixMatcher" }, "torch.unique_consecutive": { "Matcher": "ChangePrefixMatcher" From edb40427cb0d0611da6c6a85cd7974f4ac18ebc3 Mon Sep 17 00:00:00 2001 From: Manfredss Date: Thu, 2 Jul 2026 23:24:12 -0700 Subject: [PATCH 03/34] [API Compatibility] inject enable_compat(level=2) so prefix-converted calls hit the alias The default enable_compat() (level=1) does not alias paddle.*, so prefix-converted calls (torch.X -> paddle.X) would run native and reject torch-style kwargs. level=2 turns on the paddle.* alias; caller-aware dispatch keeps paddle internals native. Co-Authored-By: Claude Opus 4.8 (1M context) --- paconvert/transformer/import_transformer.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/paconvert/transformer/import_transformer.py b/paconvert/transformer/import_transformer.py index 435b4fd4c..cc524dc2a 100644 --- a/paconvert/transformer/import_transformer.py +++ b/paconvert/transformer/import_transformer.py @@ -526,19 +526,19 @@ def visit_Module(self, node): ) line_NO += 1 - # Inject `paddle.enable_compat()` right after the imports so that - # prefix-only converted calls (torch.X -> paddle.X via ChangePrefixMatcher) - # resolve to the torch-aligned paddle.compat.* implementations at runtime - # `import paddle` is included explicitly (deduped if already added) so the - # call is valid even when torch was imported as a submodule alias - # (e.g. `import torch.nn as nn` -> `import paddle.nn as nn`) + # Inject `paddle.enable_compat(level=2)` after the imports so prefix-only + # converted calls (torch.X -> paddle.X) resolve to the torch-aligned + # paddle.compat.* impls. level=2 (not the default) is required: aliasing + # the public `paddle.*` surface is opt-in, and caller-aware dispatch keeps + # paddle internals native. `import paddle` is explicit (deduped) so the call + # is valid even for submodule aliases (`import torch.nn as nn`). if paddle_package_list: log_info( self.logger, - "add 'paddle.enable_compat()' after imports", + "add 'paddle.enable_compat(level=2)' after imports", self.file_name, ) self.record_scope( (self.root, "body", 0), - ast.parse("import paddle\npaddle.enable_compat()").body, + ast.parse("import paddle\npaddle.enable_compat(level=2)").body, ) From e584efab28956e2ce6b8f822f17d5b868074b296 Mon Sep 17 00:00:00 2001 From: Manfredss Date: Mon, 6 Jul 2026 23:41:22 -0700 Subject: [PATCH 04/34] [API Compatibility] refine enable_compat injection; activate compat reset import_transformer.py: - Inject paddle.enable_compat(level=2) via a transform() post-pass so it lands after the docstring, __future__ imports and the import block (fixes a pre-existing SyntaxError where injected imports preceded `from __future__`). - Gate on real torch imports (torch_packages), not paddle_package_list, so a torch-free file importing only os/einops/setuptools no longer gains a needless paddle import or the process-global compat switch. tests: - Rename confest.py -> conftest.py so the autouse compat-reset fixture is loaded by pytest (was dead due to the typo). - Dedupe the disable logic into conftest.disable_paddle_compat(), imported by apibase and called before each torch reference exec. Co-Authored-By: Claude Opus 4.8 (1M context) --- paconvert/transformer/import_transformer.py | 109 +++++++++++++++++--- tests/apibase.py | 28 +---- tests/{confest.py => conftest.py} | 26 +++-- 3 files changed, 115 insertions(+), 48 deletions(-) rename tests/{confest.py => conftest.py} (61%) diff --git a/paconvert/transformer/import_transformer.py b/paconvert/transformer/import_transformer.py index cc524dc2a..3b838edb2 100644 --- a/paconvert/transformer/import_transformer.py +++ b/paconvert/transformer/import_transformer.py @@ -46,6 +46,9 @@ def __init__( self.imports_map[self.file]["api_alias_name_map"] = {} self.insert_pass_node = set() self.change_prefix_api_map = defaultdict(set) + # Set in visit_Module: True when this file actually imports torch (so we + # added paddle imports) and therefore needs paddle.enable_compat injected. + self.need_enable_compat = False def visit_Import(self, node): """ @@ -526,19 +529,93 @@ def visit_Module(self, node): ) line_NO += 1 - # Inject `paddle.enable_compat(level=2)` after the imports so prefix-only - # converted calls (torch.X -> paddle.X) resolve to the torch-aligned - # paddle.compat.* impls. level=2 (not the default) is required: aliasing - # the public `paddle.*` surface is opt-in, and caller-aware dispatch keeps - # paddle internals native. `import paddle` is explicit (deduped) so the call - # is valid even for submodule aliases (`import torch.nn as nn`). - if paddle_package_list: - log_info( - self.logger, - "add 'paddle.enable_compat(level=2)' after imports", - self.file_name, - ) - self.record_scope( - (self.root, "body", 0), - ast.parse("import paddle\npaddle.enable_compat(level=2)").body, - ) + # enable_compat is injected in transform() (needs all imports in the body). + # Gate on real torch imports, not paddle_package_list: the latter also holds + # MAY_TORCH packages (os/einops/setuptools) that need no compat switch. + if self.imports_map[self.file]["torch_packages"]: + self.need_enable_compat = True + + def transform(self): + super(ImportTransformer, self).transform() + self._inject_enable_compat() + + @staticmethod + def _is_future_import(node): + return isinstance(node, ast.ImportFrom) and node.module == "__future__" + + @staticmethod + def _is_import(node): + return isinstance(node, (ast.Import, ast.ImportFrom)) + + @staticmethod + def _is_docstring(node): + return ( + isinstance(node, ast.Expr) + and isinstance(node.value, ast.Constant) + and isinstance(node.value.value, str) + ) + + @staticmethod + def _is_enable_compat_call(node): + return ( + isinstance(node, ast.Expr) + and isinstance(node.value, ast.Call) + and isinstance(node.value.func, ast.Attribute) + and node.value.func.attr == "enable_compat" + and isinstance(node.value.func.value, ast.Name) + and node.value.func.value.id == "paddle" + ) + + @staticmethod + def _binds_paddle(node): + # `import paddle` or `import paddle.xxx` (no asname) binds the name `paddle` + if isinstance(node, ast.Import): + for alias_node in node.names: + if alias_node.asname is None and ( + alias_node.name == "paddle" or alias_node.name.startswith("paddle.") + ): + return True + return False + + def _inject_enable_compat(self): + """Insert ``paddle.enable_compat(level=2)`` after the docstring, + ``__future__`` imports and the import block (level=2 aliases the + torch-aligned ``paddle.compat.*`` APIs onto ``paddle.*``). Post-pass so it + is never placed above a ``__future__`` import (which is a SyntaxError). + """ + if not self.need_enable_compat: + return + + body = [n for n in self.root.body if not self._is_enable_compat_call(n)] + + # hoist all __future__ imports (they must precede every other statement) + futures = [n for n in body if self._is_future_import(n)] + body = [n for n in body if not self._is_future_import(n)] + + # hoist the module docstring if only imports precede it (we prepend imports) + doc = [] + for i, node in enumerate(body): + if self._is_docstring(node) and all(self._is_import(n) for n in body[:i]): + doc = [node] + body = body[:i] + body[i + 1 :] + break + + # split off the contiguous import block at the top of the remainder + end = 0 + while end < len(body) and self._is_import(body[end]): + end += 1 + imports, rest = body[:end], body[end:] + + # enable_compat needs the name `paddle` bound (submodule-only aliases may + # not bind it, e.g. `import torch.nn as nn` -> `import paddle.nn as nn`) + if not any(self._binds_paddle(n) for n in imports): + imports = ast.parse("import paddle").body + imports + + compat = ast.parse("paddle.enable_compat(level=2)").body + self.root.body = doc + futures + imports + compat + rest + ast.fix_missing_locations(self.root) + log_info( + self.logger, + "add 'paddle.enable_compat(level=2)' after imports", + self.file_name, + ) diff --git a/tests/apibase.py b/tests/apibase.py index f9c06adc7..0549843d7 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -20,29 +20,11 @@ import numpy as np sys.path.append(os.path.dirname(__file__) + "/..") +sys.path.append(os.path.dirname(__file__)) -from paconvert.converter import Converter - +from conftest import disable_paddle_compat -def _ensure_paddle_compat_disabled(): - """Converted Paddle code now injects ``paddle.enable_compat()``, which installs - a global ``import torch`` -> Paddle proxy and aliases ``paddle.*`` to the - torch-aligned ``paddle.compat.*`` APIs. That global state must be OFF when the - torch *reference* snippet runs, otherwise its ``import torch`` would be proxied - to Paddle and the reference would no longer be real torch. No-op when Paddle - was never imported (compat cannot be active then), so the first reference run is - unaffected. - """ - if "paddle" not in sys.modules: - return - paddle = sys.modules["paddle"] - try: - from paddle.compat.proxy import TORCH_PROXY_FINDER - - while TORCH_PROXY_FINDER in sys.meta_path: - paddle.disable_compat() - except ImportError: - pass +from paconvert.converter import Converter class APIBase(object): @@ -106,7 +88,7 @@ def run( ) assert paddle_code == expect_paddle_code, error_msg elif compared_tensor_names: - _ensure_paddle_compat_disabled() + disable_paddle_compat() pytorch_ns = {} try: exec(pytorch_code, pytorch_ns) @@ -139,7 +121,7 @@ def run( except Exception as e: raise AssertionError(f"Unable to align results: {e}") else: - _ensure_paddle_compat_disabled() + disable_paddle_compat() pytorch_ns = {} try: exec(pytorch_code, pytorch_ns) diff --git a/tests/confest.py b/tests/conftest.py similarity index 61% rename from tests/confest.py rename to tests/conftest.py index 12a31e481..c1c52f78a 100644 --- a/tests/confest.py +++ b/tests/conftest.py @@ -17,19 +17,20 @@ import pytest -@pytest.fixture(autouse=True) -def _reset_paddle_compat_mode(): - """Converted Paddle code node injects ``paddle.enable_compat()``, which flips - global state: it installs an ``import torch`` -> Paddle proxy adn aliases - ``paddle.*`` to the torch-aligned ``paddle.compat.*`` APIs. Disable it after - every test so it cannot leak into a later test (e.g., corrupt another test's) - real-torch reference run, or break tests that assume compat is off. +def disable_paddle_compat(): + """Turn OFF Paddle's torch-compat proxy if it is currently active. + + Converted Paddle code injects ``paddle.enable_compat(level=2)``, which flips + process-global state: it installs an ``import torch`` -> Paddle proxy and + aliases ``paddle.*`` to the torch-aligned ``paddle.compat.*`` APIs. That state + must be cleared so it cannot leak into (a) a later test, or (b) a torch + *reference* run within the same test, whose ``import torch`` would otherwise be + proxied to Paddle so the reference would no longer be real torch. Lazy and best-effort: a no-op when Paddle was never imported, so it does not force a Paddle import (and thus does not change torch/paddle import ordering) - for tests that never touch Paddle + for tests that never touch Paddle. """ - yield if "paddle" not in sys.modules: return paddle = sys.modules["paddle"] @@ -40,3 +41,10 @@ def _reset_paddle_compat_mode(): paddle.disable_compat() except Exception: pass + + +@pytest.fixture(autouse=True) +def _reset_paddle_compat_mode(): + """Disable torch-compat after every test so it cannot leak into a later one.""" + yield + disable_paddle_compat() From 3dcd2a1dce21547145070091e47afdef4098c84c Mon Sep 17 00:00:00 2001 From: manfredss Date: Wed, 8 Jul 2026 08:22:11 +0000 Subject: [PATCH 05/34] update ChangePrefixMatcher for those can passed under enable_compat(level=2) now. --- paconvert/api_mapping.json | 42 ++++---------------------------- tests/test_Tensor_median.py | 48 +++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 61 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 3b6d430de..0fa310c96 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -1537,18 +1537,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.max": { - "Matcher": "TensorMaxMatcher", - "paddle_api": "paddle.Tensor.max", - "min_input_args": 0, - "args_list": [ - "dim", - "keepdim", - "other" - ], - "kwargs_change": { - "dim": "axis", - "other": "y" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.maximum": { "Matcher": "ChangePrefixMatcher" @@ -1557,33 +1546,10 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.median": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.Tensor.median", - "min_input_args": 0, - "args_list": [ - "dim", - "keepdim" - ], - "kwargs_change": { - "dim": "axis" - }, - "unsupport_args": [ - "dim" - ] + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.min": { - "Matcher": "TensorMinMatcher", - "paddle_api": "paddle.Tensor.min", - "min_input_args": 0, - "args_list": [ - "dim", - "keepdim", - "other" - ], - "kwargs_change": { - "dim": "axis", - "other": "y" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.minimum": { "Matcher": "ChangePrefixMatcher" @@ -7251,7 +7217,7 @@ "Matcher": "GenericMatcher", "paddle_api": "paddle.nn.Softmax", "paddle_default_kwargs": { - "axis": -3 + "dim": -3 }, "min_input_args": 0 }, diff --git a/tests/test_Tensor_median.py b/tests/test_Tensor_median.py index 7d42a404f..e2097229e 100644 --- a/tests/test_Tensor_median.py +++ b/tests/test_Tensor_median.py @@ -38,12 +38,7 @@ def test_case_2(): result = input.median(1) """ ) - obj.run( - pytorch_code, - ["result"], - unsupport=True, - reason="paddle does not return index when dim is specified", - ) + obj.run(pytorch_code, ["result"]) def test_case_3(): @@ -54,12 +49,7 @@ def test_case_3(): result = input.median(1, keepdim=True) """ ) - obj.run( - pytorch_code, - ["result"], - unsupport=True, - reason="paddle does not return index when dim is specified", - ) + obj.run(pytorch_code, ["result"]) def test_case_4(): @@ -70,12 +60,7 @@ def test_case_4(): result = input.median(dim=1, keepdim=True) """ ) - obj.run( - pytorch_code, - ["result"], - unsupport=True, - reason="paddle does not return index when dim is specified", - ) + obj.run(pytorch_code, ["result"]) def test_case_5(): @@ -86,9 +71,26 @@ def test_case_5(): result = input.median(0) """ ) - obj.run( - pytorch_code, - ["result"], - unsupport=True, - reason="paddle does not return index when dim is specified", + obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.tensor([1.0, 2.0, 3.0, 4.0]) + result = input.median() + """ ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.tensor([[1.0, 2.0, 3.0, 4.0], [8.0, 7.0, 6.0, 5.0]]) + result = input.median(dim=1) + """ + ) + obj.run(pytorch_code, ["result"]) From 81a3c07f53a1308225644cb1c54a5fc3c66c747e Mon Sep 17 00:00:00 2001 From: manfredss Date: Wed, 8 Jul 2026 11:08:51 +0000 Subject: [PATCH 06/34] ChangePrefixMatcher for BatchNorm1d/2d/3d --- paconvert/api_mapping.json | 69 ++------------------------------------ 1 file changed, 3 insertions(+), 66 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 0fa310c96..98b69a7a3 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -6345,76 +6345,13 @@ "Matcher": "ChangePrefixMatcher" }, "torch.nn.BatchNorm1d": { - "Matcher": "ReverseMomentumMatcher", - "paddle_api": "paddle.nn.BatchNorm1D", - "min_input_args": 1, - "args_list": [ - "num_features", - "eps", - "momentum", - "affine", - "track_running_stats", - "device", - "dtype" - ], - "kwargs_change": { - "eps": "epsilon", - "affine": [ - "weight_attr", - "bias_attr" - ], - "track_running_stats": "", - "device": "", - "dtype": "" - } + "Matcher": "ChangePrefixMatcher" }, "torch.nn.BatchNorm2d": { - "Matcher": "ReverseMomentumMatcher", - "paddle_api": "paddle.nn.BatchNorm2D", - "min_input_args": 1, - "args_list": [ - "num_features", - "eps", - "momentum", - "affine", - "track_running_stats", - "device", - "dtype" - ], - "kwargs_change": { - "eps": "epsilon", - "affine": [ - "weight_attr", - "bias_attr" - ], - "track_running_stats": "", - "device": "", - "dtype": "" - } + "Matcher": "ChangePrefixMatcher" }, "torch.nn.BatchNorm3d": { - "Matcher": "ReverseMomentumMatcher", - "paddle_api": "paddle.nn.BatchNorm3D", - "min_input_args": 1, - "args_list": [ - "num_features", - "eps", - "momentum", - "affine", - "track_running_stats", - "device", - "dtype" - ], - "kwargs_change": { - "eps": "epsilon", - "affine": [ - "weight_attr", - "bias_attr" - ], - "track_running_stats": "", - "device": "", - "dtype": "" - } + "Matcher": "ChangePrefixMatcher" }, "torch.nn.Bilinear": { "Matcher": "GenericMatcher", From 8170d4f57a57a6b675395b2ea96b7e9303693851 Mon Sep 17 00:00:00 2001 From: manfredss Date: Thu, 9 Jul 2026 12:40:33 +0000 Subject: [PATCH 07/34] [API Compatibility] fix softmin/allclose/sort matchers under enable_compat Switch Tensor.allclose and Tensor.sort to ChangePrefixMatcher and keep softmin's softmax call using torch arg names (input/dim), since compat paddle APIs now accept torch-style args and reject paddle-native ones. Update tests to inject enable_compat(level=2); fix torchvision model_apibase proxy leak around the torch reference forward. --- paconvert/api_mapping.json | 32 +++---------------- tests/test_Tensor_rename.py | 8 ++++- tests/test_Tensor_split.py | 1 + ...t_add_start_docstrings_to_model_forward.py | 2 ++ tests/test_jit_ignore.py | 2 ++ tests/test_jit_load.py | 2 ++ tests/test_jit_save.py | 8 +++++ tests/test_jit_script.py | 6 ++++ tests/test_onnx_export.py | 6 ++-- tests/test_utils_model_zoo_load_url.py | 3 ++ tests/torchvision_tests/model_apibase.py | 18 +++++++++-- tests/torchvision_tests/test_Cifar10.py | 6 ++++ tests/torchvision_tests/test_Cifar100.py | 6 ++++ tests/torchvision_tests/test_DeformConv2d.py | 5 +++ tests/torchvision_tests/test_FashionMNIST.py | 7 ++++ tests/torchvision_tests/test_Flowers102.py | 7 ++++ tests/torchvision_tests/test_ImageFolder.py | 6 ++++ tests/torchvision_tests/test_MNIST.py | 7 ++++ tests/torchvision_tests/test_RoIAlign.py | 5 +++ tests/torchvision_tests/test_RoIPool.py | 5 +++ tests/torchvision_tests/test_VOCDetection.py | 3 ++ tests/torchvision_tests/test_enums.py | 1 + tests/torchvision_tests/test_googlenet.py | 1 + 23 files changed, 114 insertions(+), 33 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 98b69a7a3..859589a05 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -494,18 +494,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.allclose": { - "Matcher": "AllcloseMatcher", - "paddle_api": "paddle.Tensor.allclose", - "min_input_args": 1, - "args_list": [ - "other", - "rtol", - "atol", - "equal_nan" - ], - "kwargs_change": { - "other": "y" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.amax": { "Matcher": "ChangePrefixMatcher" @@ -1991,20 +1980,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.sort": { - "Matcher": "SortMatcher", - "paddle_api": "paddle.Tensor.sort", - "min_input_args": 0, - "args_list": [ - "dim", - "descending", - "*", - "stable", - "dim", - "descending" - ], - "kwargs_change": { - "dim": "axis" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.sparse_dim": { "Matcher": "ChangePrefixMatcher" @@ -8097,8 +8073,8 @@ "dtype" ], "kwargs_change": { - "input": "x", - "dim": "axis", + "input": "input", + "dim": "dim", "_stacklevel": "", "dtype": "dtype" }, diff --git a/tests/test_Tensor_rename.py b/tests/test_Tensor_rename.py index 4083b1ac4..d8bdb7289 100644 --- a/tests/test_Tensor_rename.py +++ b/tests/test_Tensor_rename.py @@ -29,7 +29,13 @@ def test_case_1(): ) obj.run( pytorch_code, - expect_paddle_code='import paddle\n\nx = paddle.tensor([1, 2, 3])\nx.rename(columns={"iids": iids})\n', + expect_paddle_code=""" + import paddle + + paddle.enable_compat(level=2) + x = paddle.tensor([1, 2, 3]) + x.rename(columns={"iids": iids}) + """, ) diff --git a/tests/test_Tensor_split.py b/tests/test_Tensor_split.py index 5be698bea..5741e3e02 100644 --- a/tests/test_Tensor_split.py +++ b/tests/test_Tensor_split.py @@ -100,6 +100,7 @@ def test_case_7(): """ import paddle + paddle.enable_compat(level=2) a = paddle.tensor([1, 2, 3]) str1 = "1,2,3" str1.split(",") diff --git a/tests/test_add_start_docstrings_to_model_forward.py b/tests/test_add_start_docstrings_to_model_forward.py index 509109fe9..aac30e84d 100644 --- a/tests/test_add_start_docstrings_to_model_forward.py +++ b/tests/test_add_start_docstrings_to_model_forward.py @@ -36,6 +36,8 @@ def forward(self, input_ids): import paddle import paddleformers + paddle.enable_compat(level=2) + class LlamaForCausalLM(paddle.nn.Module): @paddleformers.trainer.utils.add_start_docstrings_to_model_forward("test docstring") diff --git a/tests/test_jit_ignore.py b/tests/test_jit_ignore.py index e607a5844..39629feae 100644 --- a/tests/test_jit_ignore.py +++ b/tests/test_jit_ignore.py @@ -43,6 +43,8 @@ def helper_function(self, x): """ import paddle + paddle.enable_compat(level=2) + class MyModule(paddle.nn.Module): def forward(self, x): diff --git a/tests/test_jit_load.py b/tests/test_jit_load.py index ce977a45e..10b22c52c 100644 --- a/tests/test_jit_load.py +++ b/tests/test_jit_load.py @@ -31,6 +31,7 @@ def test_case_1(): """ import paddle + paddle.enable_compat(level=2) result = paddle.jit.load(path="model.pt") """ ) @@ -48,6 +49,7 @@ def test_case_2(): """ import paddle + paddle.enable_compat(level=2) result = paddle.jit.load(path="model.pt") """ ) diff --git a/tests/test_jit_save.py b/tests/test_jit_save.py index f0e2b4f3d..b18a18131 100644 --- a/tests/test_jit_save.py +++ b/tests/test_jit_save.py @@ -45,6 +45,8 @@ def forward(self, x): """ import paddle + paddle.enable_compat(level=2) + class MyModule(paddle.nn.Module): def __init__(self): @@ -89,6 +91,8 @@ def forward(self, x): """ import paddle + paddle.enable_compat(level=2) + class MyModule(paddle.nn.Module): def __init__(self): @@ -134,6 +138,8 @@ def forward(self, x): """ import paddle + paddle.enable_compat(level=2) + class MyModule(paddle.nn.Module): def __init__(self): @@ -180,6 +186,8 @@ def forward(self, x): """ import paddle + paddle.enable_compat(level=2) + class MyModule(paddle.nn.Module): def __init__(self): diff --git a/tests/test_jit_script.py b/tests/test_jit_script.py index 26ceaa33d..601ed577f 100644 --- a/tests/test_jit_script.py +++ b/tests/test_jit_script.py @@ -34,6 +34,8 @@ def foo(x, scale, shift): """ import paddle + paddle.enable_compat(level=2) + @paddle.jit.to_static def foo(x, scale, shift): @@ -66,6 +68,8 @@ def add(x, y): """ import paddle + paddle.enable_compat(level=2) + def add(x, y): return x + y @@ -99,6 +103,8 @@ def add(x, y): """ import paddle + paddle.enable_compat(level=2) + def add(x, y): return x + y diff --git a/tests/test_onnx_export.py b/tests/test_onnx_export.py index a3271fb35..1adec9c7d 100644 --- a/tests/test_onnx_export.py +++ b/tests/test_onnx_export.py @@ -105,12 +105,14 @@ def onnx_export(model,f): ############################## 相关utils函数,如上 ############################## + paddle.enable_compat(level=2) + class SimpleModel(paddle.nn.Module): def __init__(self): super(SimpleModel, self).__init__() - self.fc1 = paddle.compat.nn.Linear(3, 3) - self.fc2 = paddle.compat.nn.Linear(3, 1) + self.fc1 = paddle.nn.Linear(3, 3) + self.fc2 = paddle.nn.Linear(3, 1) def forward(self, x): x = paddle.relu(self.fc1(x)) diff --git a/tests/test_utils_model_zoo_load_url.py b/tests/test_utils_model_zoo_load_url.py index a23726057..46b1afdb8 100644 --- a/tests/test_utils_model_zoo_load_url.py +++ b/tests/test_utils_model_zoo_load_url.py @@ -30,6 +30,7 @@ def test_case_1(): """ import paddle + paddle.enable_compat(level=2) result = paddle.hub.load_state_dict_from_url(url="http://example.com/model.pth") """ ) @@ -47,6 +48,7 @@ def test_case_2(): """ import paddle + paddle.enable_compat(level=2) result = paddle.hub.load_state_dict_from_url( url="http://example.com/model.pth", model_dir="/tmp" ) @@ -66,6 +68,7 @@ def test_case_3(): """ import paddle + paddle.enable_compat(level=2) result = paddle.hub.load_state_dict_from_url( url="http://example.com/model.pth", model_dir="/tmp", map_location="cpu" ) diff --git a/tests/torchvision_tests/model_apibase.py b/tests/torchvision_tests/model_apibase.py index c3ee9f397..56814606d 100644 --- a/tests/torchvision_tests/model_apibase.py +++ b/tests/torchvision_tests/model_apibase.py @@ -12,10 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +import sys + import numpy as np import paddle import torch from apibase import APIBase +from conftest import disable_paddle_compat class ModelAPIBase(APIBase): @@ -44,9 +47,17 @@ def compare( else: simple_input = np.random.rand(1, 3, 224, 224).astype(np.float32) - pytorch_output = pytorch_result(torch.tensor(simple_input)) - paddle_output = paddle_result(paddle.to_tensor(simple_input)) + # The converted paddle code has globally flipped compat ON (its + # `paddle.enable_compat(level=2)` ran during exec). The torch reference + # forward below must run under REAL torch, otherwise torchvision's + # internal `import torch` / `torch.SymInt` etc. resolve through the + # paddle proxy and blow up. Disable compat for the torch forward, then + # restore it so the paddle forward matches how a user runs the output. + from paddle.compat.proxy import TORCH_PROXY_FINDER + compat_was_on = TORCH_PROXY_FINDER in sys.meta_path + disable_paddle_compat() + pytorch_output = pytorch_result(torch.tensor(simple_input)) if isinstance(pytorch_output, torch.Tensor): pytorch_numpy = pytorch_output.detach().cpu().numpy() elif isinstance(pytorch_output, tuple): @@ -56,6 +67,9 @@ def compare( else: raise ValueError("Unsupported type for pytorch_output") + if compat_was_on: + paddle.enable_compat(level=2) + paddle_output = paddle_result(paddle.to_tensor(simple_input)) if isinstance(paddle_output, paddle.Tensor): paddle_numpy = paddle_output.detach().numpy() elif isinstance(paddle_output, tuple): diff --git a/tests/torchvision_tests/test_Cifar10.py b/tests/torchvision_tests/test_Cifar10.py index 3aba0f1c6..3f886cc21 100644 --- a/tests/torchvision_tests/test_Cifar10.py +++ b/tests/torchvision_tests/test_Cifar10.py @@ -38,6 +38,7 @@ def test_case_1(): import paddle + paddle.enable_compat(level=2) train_dataset = paddle.vision.datasets.Cifar10( transform=paddle.vision.transforms.Normalize(mean=(0.5,), std=(0.5,)), download=True, @@ -67,6 +68,7 @@ def test_case_2(): import paddle + paddle.enable_compat(level=2) train_dataset = paddle.vision.datasets.Cifar10( transform=paddle.vision.transforms.Normalize(mean=(0.5,), std=(0.5,)), data_file=os.path.join("./data", "cifar-10-python.tar.gz"), @@ -99,6 +101,7 @@ def test_case_3(): import paddle + paddle.enable_compat(level=2) train_dataset = paddle.vision.datasets.Cifar10( download=True, transform=paddle.vision.transforms.Normalize(mean=(0.5,), std=(0.5,)), @@ -126,6 +129,7 @@ def test_case_4(): import paddle + paddle.enable_compat(level=2) train_dataset = paddle.vision.datasets.Cifar10( data_file=os.path.join("./data", "cifar-10-python.tar.gz") ) @@ -151,6 +155,7 @@ def test_case_5(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.Cifar10( data_file=os.path.join(root_path, "cifar-10-python.tar.gz"), mode="train" @@ -177,6 +182,7 @@ def test_case_6(): import paddle + paddle.enable_compat(level=2) train = True train_dataset = paddle.vision.datasets.Cifar10( data_file=os.path.join("./data", "cifar-10-python.tar.gz"), diff --git a/tests/torchvision_tests/test_Cifar100.py b/tests/torchvision_tests/test_Cifar100.py index a83b41f00..9a0c0851a 100644 --- a/tests/torchvision_tests/test_Cifar100.py +++ b/tests/torchvision_tests/test_Cifar100.py @@ -38,6 +38,7 @@ def test_case_1(): import paddle + paddle.enable_compat(level=2) train_dataset = paddle.vision.datasets.Cifar100( transform=paddle.vision.transforms.Normalize(mean=(0.5,), std=(0.5,)), download=True, @@ -67,6 +68,7 @@ def test_case_2(): import paddle + paddle.enable_compat(level=2) train_dataset = paddle.vision.datasets.Cifar100( transform=paddle.vision.transforms.Normalize(mean=(0.5,), std=(0.5,)), data_file=os.path.join("./data", "cifar-100-python.tar.gz"), @@ -99,6 +101,7 @@ def test_case_3(): import paddle + paddle.enable_compat(level=2) train_dataset = paddle.vision.datasets.Cifar100( download=True, transform=paddle.vision.transforms.Normalize(mean=(0.5,), std=(0.5,)), @@ -126,6 +129,7 @@ def test_case_4(): import paddle + paddle.enable_compat(level=2) train_dataset = paddle.vision.datasets.Cifar100( data_file=os.path.join("./data", "cifar-100-python.tar.gz") ) @@ -151,6 +155,7 @@ def test_case_5(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.Cifar100( data_file=os.path.join(root_path, "cifar-100-python.tar.gz"), mode="train" @@ -177,6 +182,7 @@ def test_case_6(): import paddle + paddle.enable_compat(level=2) train = True train_dataset = paddle.vision.datasets.Cifar100( data_file=os.path.join("./data", "cifar-100-python.tar.gz"), diff --git a/tests/torchvision_tests/test_DeformConv2d.py b/tests/torchvision_tests/test_DeformConv2d.py index e0cccefb3..b39f632b4 100644 --- a/tests/torchvision_tests/test_DeformConv2d.py +++ b/tests/torchvision_tests/test_DeformConv2d.py @@ -39,6 +39,7 @@ def test_case_1(): """ import paddle + paddle.enable_compat(level=2) deform_conv = paddle.vision.ops.DeformConv2D( in_channels=3, out_channels=4, @@ -65,6 +66,7 @@ def test_case_2(): """ import paddle + paddle.enable_compat(level=2) deform_conv = paddle.vision.ops.DeformConv2D( in_channels=3, out_channels=4, @@ -99,6 +101,7 @@ def test_case_3(): """ import paddle + paddle.enable_compat(level=2) deform_conv = paddle.vision.ops.DeformConv2D( kernel_size=3, in_channels=3, @@ -125,6 +128,7 @@ def test_case_4(): """ import paddle + paddle.enable_compat(level=2) deform_conv = paddle.vision.ops.DeformConv2D( in_channels=3, out_channels=64, kernel_size=3 ) @@ -153,6 +157,7 @@ def test_case_5(): """ import paddle + paddle.enable_compat(level=2) deform_conv = paddle.vision.ops.DeformConv2D( groups=1, dilation=1, diff --git a/tests/torchvision_tests/test_FashionMNIST.py b/tests/torchvision_tests/test_FashionMNIST.py index e3e8676f1..8b4a14a77 100644 --- a/tests/torchvision_tests/test_FashionMNIST.py +++ b/tests/torchvision_tests/test_FashionMNIST.py @@ -33,6 +33,7 @@ def test_case_1(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.FashionMNIST( transform=None, @@ -63,6 +64,7 @@ def test_case_2(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.FashionMNIST( transform=None, @@ -93,6 +95,7 @@ def test_case_3(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.FashionMNIST( download=False, @@ -122,6 +125,7 @@ def test_case_4(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.FashionMNIST( mode="train", @@ -150,6 +154,7 @@ def test_case_5(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.FashionMNIST( mode="train", @@ -179,6 +184,7 @@ def test_case_6(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train = True train_dataset = paddle.vision.datasets.FashionMNIST( @@ -214,6 +220,7 @@ def test_case_7(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train = True download = False diff --git a/tests/torchvision_tests/test_Flowers102.py b/tests/torchvision_tests/test_Flowers102.py index 370da747f..107775fd2 100644 --- a/tests/torchvision_tests/test_Flowers102.py +++ b/tests/torchvision_tests/test_Flowers102.py @@ -33,6 +33,7 @@ def test_case_1(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.Flowers( transform=None, @@ -65,6 +66,7 @@ def test_case_2(): import paddle + paddle.enable_compat(level=2) root_path = "./data" split = "train" train_dataset = paddle.vision.datasets.Flowers( @@ -95,6 +97,7 @@ def test_case_3(): import paddle + paddle.enable_compat(level=2) train_dataset = paddle.vision.datasets.Flowers( download=False, mode="train", @@ -124,6 +127,7 @@ def test_case_4(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.Flowers( mode="train", @@ -153,6 +157,7 @@ def test_case_5(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.Flowers( mode="test", @@ -183,6 +188,7 @@ def test_case_6(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train = True train_dataset = paddle.vision.datasets.Flowers( @@ -215,6 +221,7 @@ def test_case_7(): import paddle + paddle.enable_compat(level=2) root_path = "./data" split = "val" download = False diff --git a/tests/torchvision_tests/test_ImageFolder.py b/tests/torchvision_tests/test_ImageFolder.py index c8eec7ba7..4d45a90e8 100644 --- a/tests/torchvision_tests/test_ImageFolder.py +++ b/tests/torchvision_tests/test_ImageFolder.py @@ -34,6 +34,7 @@ def test_case_1(): import paddle + paddle.enable_compat(level=2) fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder(root=Path(fake_data_dir)) """ @@ -62,6 +63,7 @@ def test_case_2(): import cv2 import paddle + paddle.enable_compat(level=2) fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder( root=fake_data_dir, loader=lambda x: cv2.imread(x), transform=transform @@ -94,6 +96,7 @@ def test_case_3(): import cv2 import paddle + paddle.enable_compat(level=2) fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder( root=fake_data_dir, @@ -129,6 +132,7 @@ def test_case_4(): import cv2 import paddle + paddle.enable_compat(level=2) fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder( root=fake_data_dir, @@ -164,6 +168,7 @@ def test_case_5(): import cv2 import paddle + paddle.enable_compat(level=2) fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder( loader=lambda x: cv2.imread(x), @@ -193,6 +198,7 @@ def test_case_6(): """ import paddle + paddle.enable_compat(level=2) fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder(root=fake_data_dir) """ diff --git a/tests/torchvision_tests/test_MNIST.py b/tests/torchvision_tests/test_MNIST.py index 1516130cf..cefc2335c 100644 --- a/tests/torchvision_tests/test_MNIST.py +++ b/tests/torchvision_tests/test_MNIST.py @@ -33,6 +33,7 @@ def test_case_1(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.MNIST( transform=None, @@ -63,6 +64,7 @@ def test_case_2(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.MNIST( transform=None, @@ -93,6 +95,7 @@ def test_case_3(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.MNIST( download=False, @@ -122,6 +125,7 @@ def test_case_4(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.MNIST( mode="train", @@ -150,6 +154,7 @@ def test_case_5(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train_dataset = paddle.vision.datasets.MNIST( mode="train", @@ -179,6 +184,7 @@ def test_case_6(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train = True train_dataset = paddle.vision.datasets.MNIST( @@ -214,6 +220,7 @@ def test_case_7(): import paddle + paddle.enable_compat(level=2) root_path = "./data" train = True download = False diff --git a/tests/torchvision_tests/test_RoIAlign.py b/tests/torchvision_tests/test_RoIAlign.py index 65499d3ab..181323408 100644 --- a/tests/torchvision_tests/test_RoIAlign.py +++ b/tests/torchvision_tests/test_RoIAlign.py @@ -31,6 +31,7 @@ def test_case_1(): """ import paddle + paddle.enable_compat(level=2) roi_align = paddle.vision.ops.RoIAlign(output_size=(7, 7), spatial_scale=1.0) """ ) @@ -49,6 +50,7 @@ def test_case_2(): """ import paddle + paddle.enable_compat(level=2) roi_align = paddle.vision.ops.RoIAlign(output_size=(7, 7), spatial_scale=1.0) """ ) @@ -67,6 +69,7 @@ def test_case_3(): """ import paddle + paddle.enable_compat(level=2) roi_align = paddle.vision.ops.RoIAlign(spatial_scale=1.0, output_size=(7, 7)) """ ) @@ -85,6 +88,7 @@ def test_case_4(): """ import paddle + paddle.enable_compat(level=2) roi_align = paddle.vision.ops.RoIAlign(output_size=7, spatial_scale=1.0) """ ) @@ -103,6 +107,7 @@ def test_case_5(): """ import paddle + paddle.enable_compat(level=2) roi_align = paddle.vision.ops.RoIAlign(output_size=(7, 7), spatial_scale=2.0) """ ) diff --git a/tests/torchvision_tests/test_RoIPool.py b/tests/torchvision_tests/test_RoIPool.py index 6be8dfccf..4a2df6f9c 100644 --- a/tests/torchvision_tests/test_RoIPool.py +++ b/tests/torchvision_tests/test_RoIPool.py @@ -31,6 +31,7 @@ def test_case_1(): """ import paddle + paddle.enable_compat(level=2) roi_pool = paddle.vision.ops.RoIPool(output_size=(7, 7), spatial_scale=1.0) """ ) @@ -49,6 +50,7 @@ def test_case_2(): """ import paddle + paddle.enable_compat(level=2) roi_pool = paddle.vision.ops.RoIPool((7, 7), 1.0) """ ) @@ -67,6 +69,7 @@ def test_case_3(): """ import paddle + paddle.enable_compat(level=2) roi_pool = paddle.vision.ops.RoIPool(spatial_scale=1.0, output_size=(7, 7)) """ ) @@ -85,6 +88,7 @@ def test_case_4(): """ import paddle + paddle.enable_compat(level=2) roi_pool = paddle.vision.ops.RoIPool(output_size=7, spatial_scale=1.0) """ ) @@ -103,6 +107,7 @@ def test_case_5(): """ import paddle + paddle.enable_compat(level=2) roi_pool = paddle.vision.ops.RoIPool(output_size=(7, 7), spatial_scale=2.0) """ ) diff --git a/tests/torchvision_tests/test_VOCDetection.py b/tests/torchvision_tests/test_VOCDetection.py index 9a36a9ed9..7c639f181 100644 --- a/tests/torchvision_tests/test_VOCDetection.py +++ b/tests/torchvision_tests/test_VOCDetection.py @@ -58,6 +58,7 @@ def VOCDetection(*args, **kwargs): ############################## 相关utils函数,如上 ############################## + paddle.enable_compat(level=2) image_folder = VOCDetection(root="./text_data") """ ) @@ -105,6 +106,7 @@ def VOCDetection(*args, **kwargs): ############################## 相关utils函数,如上 ############################## + paddle.enable_compat(level=2) image_folder = VOCDetection( root="./text_data", image_set="train", download=False, transform=None ) @@ -154,6 +156,7 @@ def VOCDetection(*args, **kwargs): ############################## 相关utils函数,如上 ############################## + paddle.enable_compat(level=2) image_folder = VOCDetection( image_set="train", download=False, root="./text_data", transform=None ) diff --git a/tests/torchvision_tests/test_enums.py b/tests/torchvision_tests/test_enums.py index 9cef10070..0383b34f9 100644 --- a/tests/torchvision_tests/test_enums.py +++ b/tests/torchvision_tests/test_enums.py @@ -116,6 +116,7 @@ def test_case(): f""" import paddle + paddle.enable_compat(level=2) mode = "{paddle_value}" """ ) diff --git a/tests/torchvision_tests/test_googlenet.py b/tests/torchvision_tests/test_googlenet.py index 6f7880602..969f72ab7 100644 --- a/tests/torchvision_tests/test_googlenet.py +++ b/tests/torchvision_tests/test_googlenet.py @@ -90,6 +90,7 @@ def test_case_7(): """ import paddle + paddle.enable_compat(level=2) googlenet = paddle.vision.models.googlenet(pretrained=False) """ ) From f04bbf30617086b0e4b1c63a45280fa4cc02b62f Mon Sep 17 00:00:00 2001 From: manfredss Date: Thu, 9 Jul 2026 13:16:17 +0000 Subject: [PATCH 08/34] fix code conversion mis-alignment --- tests/test_Tensor_rename.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_Tensor_rename.py b/tests/test_Tensor_rename.py index d8bdb7289..37243533f 100644 --- a/tests/test_Tensor_rename.py +++ b/tests/test_Tensor_rename.py @@ -30,11 +30,11 @@ def test_case_1(): obj.run( pytorch_code, expect_paddle_code=""" - import paddle +import paddle - paddle.enable_compat(level=2) - x = paddle.tensor([1, 2, 3]) - x.rename(columns={"iids": iids}) +paddle.enable_compat(level=2) +x = paddle.tensor([1, 2, 3]) +x.rename(columns={"iids": iids}) """, ) From 838a8a58fe0d6753c14e21ea13bfc8d297eb5522 Mon Sep 17 00:00:00 2001 From: manfredss Date: Tue, 14 Jul 2026 02:57:43 +0000 Subject: [PATCH 09/34] restore test script --- scripts/ci/run_gpu_unittest.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/scripts/ci/run_gpu_unittest.sh b/scripts/ci/run_gpu_unittest.sh index d288284f2..213208edf 100644 --- a/scripts/ci/run_gpu_unittest.sh +++ b/scripts/ci/run_gpu_unittest.sh @@ -17,23 +17,23 @@ set -eo pipefail echo '******************************************************************************' echo "Installing develop GPU version paddle" -# python3.10 -m pip uninstall -y paddlepaddle paddlepaddle-gpu || true -# python3.10 -m pip install --force-reinstall --no-cache-dir --no-deps -U --pre paddlepaddle-gpu \ -# -i https://www.paddlepaddle.org.cn/packages/nightly/cu118/ \ -# --extra-index-url https://pypi.tuna.tsinghua.edu.cn/simple \ -# --timeout 120 --retries 3 -python3.10 -m pip install safetensors==0.6.2 -python3.10 -c "import paddle; print('paddle version: ', paddle.__version__); print('paddle commit info: ', paddle.__git_commit__)" +python -m pip uninstall -y paddlepaddle paddlepaddle-gpu || true +python -m pip install --force-reinstall --no-cache-dir --no-deps -U --pre paddlepaddle-gpu \ + -i https://www.paddlepaddle.org.cn/packages/nightly/cu118/ \ + --extra-index-url https://pypi.tuna.tsinghua.edu.cn/simple \ + --timeout 120 --retries 3 +python -m pip install safetensors==0.6.2 +python -c "import paddle; print('paddle version: ', paddle.__version__); print('paddle commit info: ', paddle.__git_commit__)" echo '******************************************************************************' echo "Installing paconvert requirements" -python3.10 -m pip install -r requirements.txt +python -m pip install -r requirements.txt if [ -f tests/requirements.txt ]; then - python3.10 -m pip install -r tests/requirements.txt + python -m pip install -r tests/requirements.txt fi echo '******************************************************************************' -python3.10 -c "import torch; print('torch version: ', torch.__version__, '| cuda available: ', torch.cuda.is_available())" +python -c "import torch; print('torch version: ', torch.__version__, '| cuda available: ', torch.cuda.is_available())" echo '******************************************************************************' echo "Checking code gpu unit test by pytest ..." @@ -50,21 +50,21 @@ PYTEST_IGNORE=( # Run test_cuda_stream.py separately and FIRST (GPU state is clean), # as it can segfault when run after other GPU tests (Paddle FullKernel issue). # Running in isolation prevents the segfault from killing the entire test batch. -python3.10 -m pytest -v -s -p no:warnings tests/test_cuda_stream.py 2>&1 | tee pytest.log +python -m pytest -v -s -p no:warnings tests/test_cuda_stream.py 2>&1 | tee pytest.log stream_exit=${PIPESTATUS[0]} # Run test_cuda_CUDAGraph.py in its own process as well: CUDA graph # capture/replay leaves Paddle GPU state that can natively crash later # AMP tests (e.g. test_cuda_amp_GradScaler) in the same pytest worker. -python3.10 -m pytest -v -s -p no:warnings tests/test_cuda_CUDAGraph.py 2>&1 | tee -a pytest.log +python -m pytest -v -s -p no:warnings tests/test_cuda_CUDAGraph.py 2>&1 | tee -a pytest.log cudagraph_exit=${PIPESTATUS[0]} # set_stream installs a process-global Paddle stream owned by the temporary exec # namespace. Run it separately so namespace cleanup cannot poison later GPU tests. -python3.10 -m pytest -v -s -p no:warnings tests/test_cuda_set_stream.py 2>&1 | tee -a pytest.log +python -m pytest -v -s -p no:warnings tests/test_cuda_set_stream.py 2>&1 | tee -a pytest.log setstream_exit=${PIPESTATUS[0]} -python3.10 -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" \ +python -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" \ --ignore=tests/test_cuda_stream.py \ --ignore=tests/test_cuda_CUDAGraph.py \ --ignore=tests/test_cuda_set_stream.py \ @@ -72,7 +72,7 @@ python3.10 -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" \ check_errors=${PIPESTATUS[0]} if [ ${check_errors} -ne 0 ]; then echo "Rerun GPU unit test" - python3.10 -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" \ + python -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" \ --ignore=tests/test_cuda_stream.py \ --ignore=tests/test_cuda_CUDAGraph.py \ --ignore=tests/test_cuda_set_stream.py \ From f7e1c04f6600a68ac52343844c56faeb72d6fcb2 Mon Sep 17 00:00:00 2001 From: manfredss Date: Tue, 14 Jul 2026 06:40:18 +0000 Subject: [PATCH 10/34] update min-mode consistency baselines Align expected diffs with compat injection and intentional ChangePrefixMatcher behavior. Co-Authored-By: Claude Opus 4.6 --- .../minmode_code_case/diff/combine.txt | 36 +++++++------------ .../minmode_code_case/diff/keep_same.txt | 10 +++--- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/tests/code_library/code_case/minmode_code_case/diff/combine.txt b/tests/code_library/code_case/minmode_code_case/diff/combine.txt index 04f5f6316..072cdb2ce 100644 --- a/tests/code_library/code_case/minmode_code_case/diff/combine.txt +++ b/tests/code_library/code_case/minmode_code_case/diff/combine.txt @@ -1,20 +1,15 @@ --- tests/code_library/code_case/minmode_code_case/torch_code/combine.py +++ tests/code_library/code_case/minmode_code_case/paddle_code/combine.py -@@ -1,3 +1,4 @@ +@@ -4,6 +4,8 @@ + from collections import OrderedDict + import numpy as np + import torch.nn.functional as F +import paddle - import torch - import torch.nn as nn - from torch.autograd import Function -@@ -190,7 +191,7 @@ - result = F.grid_sample(input=x, grid=grid, mode='bilinear', padding_mode= - 'border', align_corners=True) - print('#########################case27#########################') --l = nn.Linear(2, 2) -+l = paddle.compat.nn.Linear(2, 2) - net = nn.Sequential(OrderedDict([('wfs', l), ('wfs1', l)])) - memo = set() - z = net.named_modules(memo=memo, prefix='wfs', remove_duplicate=False) -@@ -461,19 +462,19 @@ ++paddle.enable_compat(level=2) + print('#########################case1#########################') + input = torch.tensor([[[[1.1524, 0.4714, 0.2857], [-1.2533, -0.9829, - + 1.0981], [0.1507, -1.1431, -2.0361]], [[0.1024, -0.4482, 0.4137], [ +@@ -461,15 +463,15 @@ result = F.softplus(x) print('#########################case75#########################') out = torch.empty([6], dtype=torch.int32) @@ -34,12 +29,7 @@ print('#########################case78#########################') x = torch.tensor([[1.0, 1.0, 1.0], [2.0, 2.0, 2.0], [3.0, 3.0, 3.0]], requires_grad=True) --linear = torch.nn.Linear(3, 4, bias=False) -+linear = paddle.compat.nn.Linear(3, 4, bias=False) - linear.weight.data.fill_(0.1) - y = linear(x) - y.detach_() -@@ -516,7 +517,7 @@ +@@ -516,7 +518,7 @@ results = x.as_strided(size=(2, 2), stride=(2, 2), storage_offset=0) print('#########################case86#########################') torch.cuda.manual_seed_all(123) @@ -48,7 +38,7 @@ print('#########################case87#########################') result = torch.as_tensor([1, 2, 3]) print('#########################case88#########################') -@@ -527,8 +528,8 @@ +@@ -527,8 +529,8 @@ print('#########################case89#########################') a = 3 out = torch.tensor([2.0, 3.0], dtype=torch.float64) @@ -59,7 +49,7 @@ print('#########################case90#########################') x = torch.tensor([[-1.0813, -0.8619, 0.7105], [0.0935, 0.138, 2.2112], [- 0.3409, -0.9828, 0.0289]]) -@@ -542,8 +543,8 @@ +@@ -542,8 +544,8 @@ print('#########################case92#########################') a = 3 out = torch.tensor([2.0, 3.0], dtype=torch.float64) @@ -70,7 +60,7 @@ print('#########################case93#########################') a = 3 out = torch.tensor([2.0, 3.0], dtype=torch.float64) -@@ -555,7 +556,7 @@ +@@ -555,7 +557,7 @@ result = x.cross(other=y, dim=1) print('#########################case95#########################') result = torch.full_like(torch.empty(2, 3), 6, dtype=torch.float64, device= diff --git a/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt b/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt index f35dd6d3d..f73d307ca 100644 --- a/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt +++ b/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt @@ -1,10 +1,10 @@ --- tests/code_library/code_case/minmode_code_case/torch_code/keep_same.py +++ tests/code_library/code_case/minmode_code_case/paddle_code/keep_same.py -@@ -1,3 +1,4 @@ -+import paddle - +@@ -1,5 +1,7 @@ import torch - import copy - ++import paddle ++paddle.enable_compat(level=2) print('#########################case1#########################') + result = torch.BFloat16Tensor([1.5, 2, 3]) + print('#########################case2#########################') From 5fe7de17f8be08e9e745eddda7de6a1071585534 Mon Sep 17 00:00:00 2001 From: Manfredss Date: Tue, 14 Jul 2026 01:36:21 -0700 Subject: [PATCH 11/34] fix default-mode consistency: dedupe injected imports, update baselines Deduplicate paddle_package_list in ImportTransformer.visit_Module: since imports are now batched into one record_scope call, its cross-call dedup no longer removes duplicates, producing two 'import paddle' lines when a file imports multiple torch-family packages (e.g. torchvision + datasets). Regenerate default-mode goldens for the paddle.enable_compat(level=2) injection and the intentional compat-prefix removals (equal, BatchNorm1d/2d), matching the min-mode baseline update in f7e1c04. Co-Authored-By: Claude Fable 5 --- paconvert/transformer/import_transformer.py | 2 +- .../code_case/paddle_code/api_paddle_Generator.py | 1 + .../code_library/code_case/paddle_code/api_paddle_Size.py | 1 + .../code_case/paddle_code/api_paddle_Tensor2Float.py | 1 + .../code_case/paddle_code/api_paddle_Tensor2Int.py | 1 + .../code_case/paddle_code/api_paddle_Tensor2Long.py | 1 + .../code_case/paddle_code/api_paddle_Tensor_expand.py | 1 + .../code_case/paddle_code/api_paddle_Tensor_new_empty.py | 1 + .../code_case/paddle_code/api_paddle_Tensor_new_full.py | 1 + .../code_case/paddle_code/api_paddle_Tensor_new_ones.py | 1 + .../code_case/paddle_code/api_paddle_Tensor_new_tensor.py | 1 + .../code_case/paddle_code/api_paddle_Tensor_new_zeros.py | 1 + .../code_case/paddle_code/api_paddle_Tensor_normal_.py | 1 + .../code_case/paddle_code/api_paddle_Tensor_to.py | 1 + .../code_case/paddle_code/api_paddle_Tensor_uniform_.py | 1 + .../code_case/paddle_code/api_paddle_cuda_is_available.py | 1 + .../code_case/paddle_code/api_paddle_equall.py | 3 ++- .../code_case/paddle_code/api_paddle_index_copy_.py | 1 + .../code_case/paddle_code/api_paddle_io_BatchSampler.py | 1 + .../paddle_code/api_paddle_nn_BCEWithLogitsLoss.py | 1 + .../code_case/paddle_code/api_paddle_nn_BatchNorm1D.py | 7 ++++--- .../code_case/paddle_code/api_paddle_nn_BatchNorm2D.py | 7 ++++--- .../code_case/paddle_code/api_paddle_nn_InstanceNorm3D.py | 1 + .../paddle_code/api_paddle_nn_functional_interpolate.py | 1 + .../code_case/paddle_code/api_paddle_permute.py | 1 + .../code_case/paddle_code/api_paddle_randint.py | 1 + .../code_case/paddle_code/api_paddle_random_manual_seed.py | 1 + .../code_case/paddle_code/api_paddle_sigmoid.py | 1 + .../code_case/paddle_code/api_paddle_to_tensor.py | 1 + .../code_case/paddle_code/api_paddle_version.py | 1 + .../code_case/paddle_code/api_remove_decorator.py | 1 + .../paddle_code/attribute_paddle_Tensor_requires_grad.py | 1 + .../code_case/paddle_code/attribute_setattr.py | 2 ++ .../code_case/paddle_code/attribute_visit_name.py | 2 ++ .../code_case/paddle_code/class_method_static_call.py | 2 ++ .../code_library/code_case/paddle_code/import_analysis.py | 3 ++- .../code_case/paddle_code/insert_pass_in_ast_if.py | 1 + tests/code_library/code_case/paddle_code/mark_unsupport.py | 1 + .../code_case/paddle_code/may_paddle_package_list.py | 1 + .../code_case/paddle_code/package_visit_name.py | 1 + tests/code_library/code_case/paddle_code/paddle_llama.py | 1 + tests/code_library/code_case/paddle_code/paddlenlp_Qwen.py | 1 + .../code_case/paddle_code/simplified_name_call.py | 1 + tests/code_library/code_case/paddle_code/type_hinting.py | 1 + 44 files changed, 55 insertions(+), 9 deletions(-) diff --git a/paconvert/transformer/import_transformer.py b/paconvert/transformer/import_transformer.py index 17bb04d80..b9ebd007d 100644 --- a/paconvert/transformer/import_transformer.py +++ b/paconvert/transformer/import_transformer.py @@ -515,7 +515,7 @@ def visit_Module(self, node): paddle_package_list.append(may_torch_package) import_nodes = [] - for paddle_package in paddle_package_list: + for paddle_package in dict.fromkeys(paddle_package_list): import_nodes.extend(ast.parse(f"import {paddle_package}").body) has_torch_package = bool(self.imports_map[self.file]["torch_packages"]) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Generator.py b/tests/code_library/code_case/paddle_code/api_paddle_Generator.py index d88f12db0..fca12b0a1 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Generator.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Generator.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") g_cpu = paddle.Generator() print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Size.py b/tests/code_library/code_case/paddle_code/api_paddle_Size.py index 138e8a43d..bb3223f25 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Size.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Size.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") print(paddle.Size([2, 8, 64, 64])) print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Float.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Float.py index f89a88122..13c4be3da 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Float.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Float.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Int.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Int.py index 3a0c2ade8..878784c31 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Int.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Int.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Long.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Long.py index 7610dc9e2..7bb44c307 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Long.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Long.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_expand.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_expand.py index c4e748f43..1994e001e 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_expand.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_expand.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") x = paddle.tensor([[1], [2], [3]]) y = x.expand(3, 4) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_empty.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_empty.py index 49d9e3991..d97caa2e7 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_empty.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_empty.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3], dtype=paddle.int64) b = a.new_empty([3, 4], dtype=paddle.float64, requires_grad=True, pin_memory=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_full.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_full.py index aae3ea427..35ee65dcf 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_full.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_full.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3], dtype=paddle.int64) b = a.new_full([3, 4], 2.43, dtype=paddle.float64, requires_grad=True, pin_memory=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_ones.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_ones.py index a447b4468..4f010f6d0 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_ones.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_ones.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3], dtype=paddle.int64) b = a.new_ones([3, 4], dtype=paddle.float64, requires_grad=True, pin_memory=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_tensor.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_tensor.py index 90c212d12..c70e047da 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_tensor.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_tensor.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3]) b = a.new_tensor([4, 5, 6], dtype=paddle.float64, requires_grad=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_zeros.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_zeros.py index 973c7afec..01de2fcd2 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_zeros.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_zeros.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3], dtype=paddle.int64) b = a.new_zeros([3, 4], dtype=paddle.float64, requires_grad=True, pin_memory=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_normal_.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_normal_.py index 3b7802e57..277c5253b 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_normal_.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_normal_.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 3, 4, 9, 0.5, 1.5]) a = a.normal_(0.2, 0.3) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_to.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_to.py index b227c47a4..7abf8752c 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_to.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_to.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") cpu = paddle.device("cpu") a = paddle.randn(2, 3) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_uniform_.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_uniform_.py index 830049a4f..5153352c1 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_uniform_.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_uniform_.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 3, 4, 9, 0.5, 1.5]) c = paddle.tensor(a.uniform_(2, 6)) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_cuda_is_available.py b/tests/code_library/code_case/paddle_code/api_paddle_cuda_is_available.py index 87c4d2569..dcd6681c8 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_cuda_is_available.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_cuda_is_available.py @@ -1,4 +1,5 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") paddle.cuda.is_available() diff --git a/tests/code_library/code_case/paddle_code/api_paddle_equall.py b/tests/code_library/code_case/paddle_code/api_paddle_equall.py index d23bc1966..4863b8a75 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_equall.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_equall.py @@ -1,4 +1,5 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") -r = paddle.compat.equal(paddle.tensor([1, 2]), paddle.tensor([1, 2])) +r = paddle.equal(paddle.tensor([1, 2]), paddle.tensor([1, 2])) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_index_copy_.py b/tests/code_library/code_case/paddle_code/api_paddle_index_copy_.py index 75ecc6dc7..d26953e95 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_index_copy_.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_index_copy_.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") x = paddle.zeros(5, 3) t = paddle.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=paddle.float) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_io_BatchSampler.py b/tests/code_library/code_case/paddle_code/api_paddle_io_BatchSampler.py index 5367719d9..0c97954db 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_io_BatchSampler.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_io_BatchSampler.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") o = list(paddle.utils.data.BatchSampler(range(10), batch_size=3, drop_last=True)) print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BCEWithLogitsLoss.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BCEWithLogitsLoss.py index 8b1cbffc5..fb2e5e375 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BCEWithLogitsLoss.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BCEWithLogitsLoss.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") loss = paddle.nn.BCEWithLogitsLoss(reduction="none") input = paddle.tensor([1.0, 0.7, 0.2], requires_grad=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py index 5d29e9551..82a582183 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py @@ -1,8 +1,9 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") -paddle.compat.nn.BatchNorm1d(3, eps=0.001, momentum=0.01) +paddle.nn.BatchNorm1d(3, eps=0.001, momentum=0.01) print("#########################case2#########################") -bn = paddle.compat.nn.BatchNorm1d(27) +bn = paddle.nn.BatchNorm1d(27) print("#########################case3#########################") -paddle.compat.nn.BatchNorm1d(10, eps=1e-05, affine=False) +paddle.nn.BatchNorm1d(10, eps=1e-05, affine=False) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py index e5b22eae8..fa50e4089 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py @@ -1,8 +1,9 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") -bn = paddle.compat.nn.BatchNorm2d(5) +bn = paddle.nn.BatchNorm2d(5) print("#########################case2#########################") -bn = paddle.compat.nn.BatchNorm2d(27) +bn = paddle.nn.BatchNorm2d(27) print("#########################case3#########################") -paddle.compat.nn.BatchNorm2d(10, eps=1e-05, affine=False) +paddle.nn.BatchNorm2d(10, eps=1e-05, affine=False) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_InstanceNorm3D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_InstanceNorm3D.py index 2a583c9df..be1645f4d 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_InstanceNorm3D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_InstanceNorm3D.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") m = paddle.nn.InstanceNorm3D(num_features=100) input = paddle.randn(20, 100, 35, 45, 10) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_functional_interpolate.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_functional_interpolate.py index 3ea8841b3..a8fd2004b 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_functional_interpolate.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_functional_interpolate.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.nn.functional.interpolate(paddle.randn(1, 2, 20, 20), [24, 24]) print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_permute.py b/tests/code_library/code_case/paddle_code/api_paddle_permute.py index 4f29c79ab..0be2c69b9 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_permute.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_permute.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") x = paddle.rand([2, 3, 4, 4]) x.permute(0, 2, 3, 1) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_randint.py b/tests/code_library/code_case/paddle_code/api_paddle_randint.py index df404ab02..c37c56d0b 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_randint.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_randint.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.randint(2, 5, [3, 4], device=paddle.device("cuda")) print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_random_manual_seed.py b/tests/code_library/code_case/paddle_code/api_paddle_random_manual_seed.py index 36dd99e87..e340982c2 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_random_manual_seed.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_random_manual_seed.py @@ -1,4 +1,5 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") paddle.manual_seed(23) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_sigmoid.py b/tests/code_library/code_case/paddle_code/api_paddle_sigmoid.py index aeec7f65f..f40c50d5c 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_sigmoid.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_sigmoid.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") t = paddle.randn(4) paddle.sigmoid(t) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_to_tensor.py b/tests/code_library/code_case/paddle_code/api_paddle_to_tensor.py index a0a508514..aa9038911 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_to_tensor.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_to_tensor.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor( paddle.tensor([2, 3, 4]), diff --git a/tests/code_library/code_case/paddle_code/api_paddle_version.py b/tests/code_library/code_case/paddle_code/api_paddle_version.py index 967b882e5..3bac91fd6 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_version.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_version.py @@ -1,3 +1,4 @@ import paddle +paddle.enable_compat(level=2) print(paddle.__version__) diff --git a/tests/code_library/code_case/paddle_code/api_remove_decorator.py b/tests/code_library/code_case/paddle_code/api_remove_decorator.py index 9fe54061b..26c7ce5d6 100644 --- a/tests/code_library/code_case/paddle_code/api_remove_decorator.py +++ b/tests/code_library/code_case/paddle_code/api_remove_decorator.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py b/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py index 10351335a..02842cd43 100644 --- a/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py +++ b/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") data = paddle.tensor([23.0, 32.0, 43.0]) if not data.requires_grad: diff --git a/tests/code_library/code_case/paddle_code/attribute_setattr.py b/tests/code_library/code_case/paddle_code/attribute_setattr.py index 381ae1dba..31c3eca3b 100644 --- a/tests/code_library/code_case/paddle_code/attribute_setattr.py +++ b/tests/code_library/code_case/paddle_code/attribute_setattr.py @@ -1,5 +1,7 @@ import paddle +paddle.enable_compat(level=2) + def add_module(self, name, module): self.add_module(f"{name} - {len(self) + 1}", module) diff --git a/tests/code_library/code_case/paddle_code/attribute_visit_name.py b/tests/code_library/code_case/paddle_code/attribute_visit_name.py index f1b9c1f39..fca18304e 100644 --- a/tests/code_library/code_case/paddle_code/attribute_visit_name.py +++ b/tests/code_library/code_case/paddle_code/attribute_visit_name.py @@ -1,6 +1,8 @@ import paddle import paddleformers +paddle.enable_compat(level=2) + class A(paddle.nn.Module): def __init__(self, data: paddle.Tensor): diff --git a/tests/code_library/code_case/paddle_code/class_method_static_call.py b/tests/code_library/code_case/paddle_code/class_method_static_call.py index 37add8025..c2e1588d2 100644 --- a/tests/code_library/code_case/paddle_code/class_method_static_call.py +++ b/tests/code_library/code_case/paddle_code/class_method_static_call.py @@ -1,5 +1,7 @@ import paddle +paddle.enable_compat(level=2) + class PT_Optimizer(paddle.optimizer.Optimizer): pass diff --git a/tests/code_library/code_case/paddle_code/import_analysis.py b/tests/code_library/code_case/paddle_code/import_analysis.py index 78f0b5776..224825e00 100644 --- a/tests/code_library/code_case/paddle_code/import_analysis.py +++ b/tests/code_library/code_case/paddle_code/import_analysis.py @@ -1,4 +1,3 @@ -import paddle from . import datasets from .datasets import x from yolov3.datasets import a @@ -6,3 +5,5 @@ from .torchvision import x from yolov3.torchvision import a from baidubce.services.bos.bos_client import BosClient +import paddle +paddle.enable_compat(level=2) diff --git a/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py b/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py index 40ed1dca0..16d7805f1 100644 --- a/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py +++ b/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py @@ -2,6 +2,7 @@ import paddle +paddle.enable_compat(level=2) if TYPE_CHECKING: pass import warnings diff --git a/tests/code_library/code_case/paddle_code/mark_unsupport.py b/tests/code_library/code_case/paddle_code/mark_unsupport.py index 40407f27f..b6174f2da 100644 --- a/tests/code_library/code_case/paddle_code/mark_unsupport.py +++ b/tests/code_library/code_case/paddle_code/mark_unsupport.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) paddle.add _LOCAL_PROCESS_GROUP = None _MISSING_LOCAL_PG_ERROR = "Local process group is not yet created! Please use detectron2's `launch()` to start processes and initialize pytorch process group. If you need to start processes in other ways, please call comm.create_local_process_group(num_workers_per_machine) after calling torch.distributed.init_process_group()." diff --git a/tests/code_library/code_case/paddle_code/may_paddle_package_list.py b/tests/code_library/code_case/paddle_code/may_paddle_package_list.py index 1ae4ca251..64fbdc993 100644 --- a/tests/code_library/code_case/paddle_code/may_paddle_package_list.py +++ b/tests/code_library/code_case/paddle_code/may_paddle_package_list.py @@ -5,6 +5,7 @@ import setuptools from numpy.random import randint +paddle.enable_compat(level=2) print("#########################case1#########################") paddle.distributed.get_world_size() print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/package_visit_name.py b/tests/code_library/code_case/paddle_code/package_visit_name.py index e8bf8505a..8f73b17ac 100644 --- a/tests/code_library/code_case/paddle_code/package_visit_name.py +++ b/tests/code_library/code_case/paddle_code/package_visit_name.py @@ -1,6 +1,7 @@ import paddle import paddleformers +paddle.enable_compat(level=2) setattr(paddle, "nn", nn_mymodule) hasattr(paddle, "nn") hasattr(paddle, "__version__") diff --git a/tests/code_library/code_case/paddle_code/paddle_llama.py b/tests/code_library/code_case/paddle_code/paddle_llama.py index 20b1adf47..0c18e6b25 100644 --- a/tests/code_library/code_case/paddle_code/paddle_llama.py +++ b/tests/code_library/code_case/paddle_code/paddle_llama.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") model_parallel_size_0 = ( paddle.distributed.fleet.base.topology._HYBRID_PARALLEL_GROUP._mp_degree diff --git a/tests/code_library/code_case/paddle_code/paddlenlp_Qwen.py b/tests/code_library/code_case/paddle_code/paddlenlp_Qwen.py index 8abecc2c3..6ad21c77b 100644 --- a/tests/code_library/code_case/paddle_code/paddlenlp_Qwen.py +++ b/tests/code_library/code_case/paddle_code/paddlenlp_Qwen.py @@ -72,6 +72,7 @@ def _rotate_half(x): ############################## 相关utils函数,如上 ############################## +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/simplified_name_call.py b/tests/code_library/code_case/paddle_code/simplified_name_call.py index 88814d982..e6746bdc5 100644 --- a/tests/code_library/code_case/paddle_code/simplified_name_call.py +++ b/tests/code_library/code_case/paddle_code/simplified_name_call.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) a = paddle.tensor([1]) b = paddle.tensor([2]) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/type_hinting.py b/tests/code_library/code_case/paddle_code/type_hinting.py index e3738d091..f74ec5e2b 100644 --- a/tests/code_library/code_case/paddle_code/type_hinting.py +++ b/tests/code_library/code_case/paddle_code/type_hinting.py @@ -2,6 +2,7 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") Union[Tuple, paddle.BoolTensor] print("#########################case2#########################") From 14d8aeb59a42dc1f831ce8396436450eef79b0cd Mon Sep 17 00:00:00 2001 From: manfredss Date: Wed, 15 Jul 2026 09:06:43 +0000 Subject: [PATCH 12/34] Simplify ImportTransformer.visit_Module to insert paddle imports and a single paddle.enable_compat(level=2) on top of the already-cleaned node, dropping redundant enable_compat/torch-package scans and adding log_info --- paconvert/api_matcher.py | 4 +- paconvert/transformer/import_transformer.py | 49 +++++++------- .../minmode_code_case/diff/combine.txt | 66 ++++++++++++++++++- .../minmode_code_case/diff/keep_same.txt | 10 ++- .../paddle_code/api_paddle_Generator.py | 1 + .../code_case/paddle_code/api_paddle_Size.py | 1 + .../paddle_code/api_paddle_Tensor2Float.py | 1 + .../paddle_code/api_paddle_Tensor2Int.py | 1 + .../paddle_code/api_paddle_Tensor2Long.py | 1 + .../paddle_code/api_paddle_Tensor_expand.py | 1 + .../api_paddle_Tensor_new_empty.py | 1 + .../paddle_code/api_paddle_Tensor_new_full.py | 1 + .../paddle_code/api_paddle_Tensor_new_ones.py | 1 + .../api_paddle_Tensor_new_tensor.py | 1 + .../api_paddle_Tensor_new_zeros.py | 1 + .../paddle_code/api_paddle_Tensor_normal_.py | 1 + .../paddle_code/api_paddle_Tensor_to.py | 1 + .../paddle_code/api_paddle_Tensor_uniform_.py | 1 + .../api_paddle_cuda_is_available.py | 1 + .../paddle_code/api_paddle_equall.py | 3 +- .../paddle_code/api_paddle_index_copy_.py | 1 + .../paddle_code/api_paddle_io_BatchSampler.py | 1 + .../api_paddle_nn_BCEWithLogitsLoss.py | 1 + .../paddle_code/api_paddle_nn_BatchNorm1D.py | 7 +- .../paddle_code/api_paddle_nn_BatchNorm2D.py | 7 +- .../api_paddle_nn_InstanceNorm3D.py | 1 + .../api_paddle_nn_functional_interpolate.py | 1 + .../paddle_code/api_paddle_permute.py | 1 + .../paddle_code/api_paddle_randint.py | 1 + .../api_paddle_random_manual_seed.py | 1 + .../paddle_code/api_paddle_sigmoid.py | 1 + .../paddle_code/api_paddle_to_tensor.py | 1 + .../paddle_code/api_paddle_version.py | 1 + .../paddle_code/api_remove_decorator.py | 1 + .../attribute_paddle_Tensor_requires_grad.py | 1 + .../paddle_code/attribute_setattr.py | 2 + .../paddle_code/attribute_visit_name.py | 2 + .../paddle_code/class_method_static_call.py | 2 + .../code_case/paddle_code/import_analysis.py | 4 +- .../paddle_code/insert_pass_in_ast_if.py | 1 + .../code_case/paddle_code/mark_unsupport.py | 1 + .../paddle_code/may_paddle_package_list.py | 1 + .../paddle_code/package_visit_name.py | 1 + .../code_case/paddle_code/paddle_llama.py | 1 + .../code_case/paddle_code/paddlenlp_Qwen.py | 1 + .../paddle_code/simplified_name_call.py | 1 + .../code_case/paddle_code/type_hinting.py | 1 + 47 files changed, 156 insertions(+), 36 deletions(-) diff --git a/paconvert/api_matcher.py b/paconvert/api_matcher.py index ad52765e8..de4e99865 100644 --- a/paconvert/api_matcher.py +++ b/paconvert/api_matcher.py @@ -5820,7 +5820,9 @@ def reduce_scatter_tensor(output, input, op, group, async_op): if input.shape[0] == world_size: input_list = paddle.unstack(input, axis=0) else: - input_list = paddle.split(input, num_or_sections=world_size, axis=0) + input_list = paddle.tensor.split( + input, num_or_sections=world_size, axis=0 + ) paddle.distributed.reduce_scatter(output, input_list, op, group, async_op) """ ) diff --git a/paconvert/transformer/import_transformer.py b/paconvert/transformer/import_transformer.py index 17bb04d80..8a9d225f3 100644 --- a/paconvert/transformer/import_transformer.py +++ b/paconvert/transformer/import_transformer.py @@ -514,28 +514,31 @@ def visit_Module(self, node): for may_torch_package in self.imports_map[self.file]["may_torch_packages"]: paddle_package_list.append(may_torch_package) - import_nodes = [] + import_code = "" for paddle_package in paddle_package_list: - import_nodes.extend(ast.parse(f"import {paddle_package}").body) - - has_torch_package = bool(self.imports_map[self.file]["torch_packages"]) - - has_enable_compat = any( - isinstance(body_node, ast.Expr) - and isinstance(body_node.value, ast.Call) - and isinstance(body_node.value.func, ast.Attribute) - and body_node.value.func.attr == "enable_compat" - and isinstance(body_node.value.func.value, ast.Name) - and body_node.value.func.value.id == "paddle" - for body_node in node.body - ) - if has_torch_package and not has_enable_compat: - import_nodes.extend(ast.parse("paddle.enable_compat(level=2)").body) - - import_end = 1 if node.body and ast.get_docstring(node, clean=False) else 0 - while import_end < len(node.body) and isinstance( - node.body[import_end], (ast.Import, ast.ImportFrom) - ): - import_end += 1 - self.record_scope((self.root, "body", import_end), import_nodes) + import_code += f"import {paddle_package}\n" + + # Under `paddle.enable_compat(level=2)` the prefix-converted calls + # (torch.X -> paddle.X) resolve to the torch-aligned paddle.compat.* impls, + # so inject it once when `import paddle` is added. isort/black dedupe repeats. + if "paddle" in paddle_package_list: + import_code += "paddle.enable_compat(level=2)\n" + + if import_code: + log_info( + self.logger, + f"add '{import_code.strip()}' ", + self.file_name, + ) + # insert after the module docstring and any surviving (non-torch) + # imports so `enable_compat` lands right below the whole import block; + # isort/black then regroup and dedupe the imports. + import_end = 1 if ast.get_docstring(node, clean=False) else 0 + while import_end < len(node.body) and isinstance( + node.body[import_end], (ast.Import, ast.ImportFrom) + ): + import_end += 1 + self.record_scope( + (self.root, "body", import_end), ast.parse(import_code).body + ) return node diff --git a/tests/code_library/code_case/minmode_code_case/diff/combine.txt b/tests/code_library/code_case/minmode_code_case/diff/combine.txt index 072cdb2ce..3396c8d54 100644 --- a/tests/code_library/code_case/minmode_code_case/diff/combine.txt +++ b/tests/code_library/code_case/minmode_code_case/diff/combine.txt @@ -1,71 +1,133 @@ ---- tests/code_library/code_case/minmode_code_case/torch_code/combine.py -+++ tests/code_library/code_case/minmode_code_case/paddle_code/combine.py +--- /workspace/paconvert/tests/code_library/code_case/minmode_code_case/torch_code/combine.py ++++ /workspace/paconvert/tests/code_library/code_case/minmode_code_case/convert_paddle_code/combine.py @@ -4,6 +4,8 @@ from collections import OrderedDict + import numpy as np + import torch.nn.functional as F + +import paddle + +paddle.enable_compat(level=2) + print('#########################case1#########################') + input = torch.tensor([[[[1.1524, 0.4714, 0.2857], [-1.2533, -0.9829, - + 1.0981], [0.1507, -1.1431, -2.0361]], [[0.1024, -0.4482, 0.4137], [ + @@ -461,15 +463,15 @@ result = F.softplus(x) + print('#########################case75#########################') + out = torch.empty([6], dtype=torch.int32) + -result = torch.randperm(6, out=out, dtype=torch.int32, layout=torch.strided, + - device=torch.device('cpu'), pin_memory=False, requires_grad=False) + +result = torch.randperm(6, out=out, dtype=torch.int32, device=torch.device( + + 'cpu'), pin_memory=False, requires_grad=False) + print('#########################case76#########################') + torch.cuda.manual_seed(123) + -result = torch.cuda.initial_seed() + +result = paddle.get_cuda_rng_state()[0].current_seed() + print('#########################case77#########################') + x = torch.tensor([1.0, 2.0, 3.0]) + result = x.new_empty(size=(2, 3), dtype=torch.float64, device='cpu', + - requires_grad=True, layout=torch.strided, pin_memory=False) + + requires_grad=True, pin_memory=False) + print('#########################case78#########################') + x = torch.tensor([[1.0, 1.0, 1.0], [2.0, 2.0, 2.0], [3.0, 3.0, 3.0]], + requires_grad=True) + @@ -516,7 +518,7 @@ results = x.as_strided(size=(2, 2), stride=(2, 2), storage_offset=0) + print('#########################case86#########################') + torch.cuda.manual_seed_all(123) + -result = torch.cuda.initial_seed() + +result = paddle.get_cuda_rng_state()[0].current_seed() + print('#########################case87#########################') + result = torch.as_tensor([1, 2, 3]) + print('#########################case88#########################') + @@ -527,8 +529,8 @@ print('#########################case89#########################') + a = 3 + out = torch.tensor([2.0, 3.0], dtype=torch.float64) + -result = torch.rand(size=(a, a), generator=None, out=out, dtype=torch. + - float64, device=torch.device('cpu'), requires_grad=True, pin_memory=False) + +result = torch.rand(size=(a, a), out=out, dtype=torch.float64, device=torch + + .device('cpu'), requires_grad=True, pin_memory=False) + print('#########################case90#########################') + x = torch.tensor([[-1.0813, -0.8619, 0.7105], [0.0935, 0.138, 2.2112], [- + 0.3409, -0.9828, 0.0289]]) + @@ -542,8 +544,8 @@ print('#########################case92#########################') + a = 3 + out = torch.tensor([2.0, 3.0], dtype=torch.float64) + -result = torch.randn(size=(a, a), generator=None, out=out, dtype=torch. + - float64, device=torch.device('cpu'), requires_grad=True, pin_memory=False) + +result = torch.randn(size=(a, a), out=out, dtype=torch.float64, device= + + torch.device('cpu'), requires_grad=True, pin_memory=False) + print('#########################case93#########################') + a = 3 + out = torch.tensor([2.0, 3.0], dtype=torch.float64) + @@ -555,7 +557,7 @@ result = x.cross(other=y, dim=1) + print('#########################case95#########################') + result = torch.full_like(torch.empty(2, 3), 6, dtype=torch.float64, device= + - 'cpu', requires_grad=True, memory_format=torch.preserve_format) + + 'cpu', requires_grad=True) + print('#########################case96#########################') + result = torch.ones_like(torch.empty(2, 3), dtype=torch.float64, + requires_grad=True, device=None) diff --git a/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt b/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt index f73d307ca..566d84ef3 100644 --- a/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt +++ b/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt @@ -1,10 +1,16 @@ ---- tests/code_library/code_case/minmode_code_case/torch_code/keep_same.py -+++ tests/code_library/code_case/minmode_code_case/paddle_code/keep_same.py +--- /workspace/paconvert/tests/code_library/code_case/minmode_code_case/torch_code/keep_same.py ++++ /workspace/paconvert/tests/code_library/code_case/minmode_code_case/convert_paddle_code/keep_same.py @@ -1,5 +1,7 @@ import torch + import copy + +import paddle + +paddle.enable_compat(level=2) + print('#########################case1#########################') + result = torch.BFloat16Tensor([1.5, 2, 3]) + print('#########################case2#########################') diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Generator.py b/tests/code_library/code_case/paddle_code/api_paddle_Generator.py index d88f12db0..fca12b0a1 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Generator.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Generator.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") g_cpu = paddle.Generator() print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Size.py b/tests/code_library/code_case/paddle_code/api_paddle_Size.py index 138e8a43d..bb3223f25 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Size.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Size.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") print(paddle.Size([2, 8, 64, 64])) print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Float.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Float.py index f89a88122..13c4be3da 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Float.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Float.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Int.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Int.py index 3a0c2ade8..878784c31 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Int.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Int.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Long.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Long.py index 7610dc9e2..7bb44c307 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Long.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor2Long.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_expand.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_expand.py index c4e748f43..1994e001e 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_expand.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_expand.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") x = paddle.tensor([[1], [2], [3]]) y = x.expand(3, 4) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_empty.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_empty.py index 49d9e3991..d97caa2e7 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_empty.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_empty.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3], dtype=paddle.int64) b = a.new_empty([3, 4], dtype=paddle.float64, requires_grad=True, pin_memory=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_full.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_full.py index aae3ea427..35ee65dcf 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_full.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_full.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3], dtype=paddle.int64) b = a.new_full([3, 4], 2.43, dtype=paddle.float64, requires_grad=True, pin_memory=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_ones.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_ones.py index a447b4468..4f010f6d0 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_ones.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_ones.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3], dtype=paddle.int64) b = a.new_ones([3, 4], dtype=paddle.float64, requires_grad=True, pin_memory=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_tensor.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_tensor.py index 90c212d12..c70e047da 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_tensor.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_tensor.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3]) b = a.new_tensor([4, 5, 6], dtype=paddle.float64, requires_grad=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_zeros.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_zeros.py index 973c7afec..01de2fcd2 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_zeros.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_new_zeros.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 2, 3], dtype=paddle.int64) b = a.new_zeros([3, 4], dtype=paddle.float64, requires_grad=True, pin_memory=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_normal_.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_normal_.py index 3b7802e57..277c5253b 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_normal_.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_normal_.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 3, 4, 9, 0.5, 1.5]) a = a.normal_(0.2, 0.3) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_to.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_to.py index b227c47a4..7abf8752c 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_to.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_to.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") cpu = paddle.device("cpu") a = paddle.randn(2, 3) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_uniform_.py b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_uniform_.py index 830049a4f..5153352c1 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_Tensor_uniform_.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_Tensor_uniform_.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor([1, 3, 4, 9, 0.5, 1.5]) c = paddle.tensor(a.uniform_(2, 6)) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_cuda_is_available.py b/tests/code_library/code_case/paddle_code/api_paddle_cuda_is_available.py index 87c4d2569..dcd6681c8 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_cuda_is_available.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_cuda_is_available.py @@ -1,4 +1,5 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") paddle.cuda.is_available() diff --git a/tests/code_library/code_case/paddle_code/api_paddle_equall.py b/tests/code_library/code_case/paddle_code/api_paddle_equall.py index d23bc1966..4863b8a75 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_equall.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_equall.py @@ -1,4 +1,5 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") -r = paddle.compat.equal(paddle.tensor([1, 2]), paddle.tensor([1, 2])) +r = paddle.equal(paddle.tensor([1, 2]), paddle.tensor([1, 2])) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_index_copy_.py b/tests/code_library/code_case/paddle_code/api_paddle_index_copy_.py index 75ecc6dc7..d26953e95 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_index_copy_.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_index_copy_.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") x = paddle.zeros(5, 3) t = paddle.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=paddle.float) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_io_BatchSampler.py b/tests/code_library/code_case/paddle_code/api_paddle_io_BatchSampler.py index 5367719d9..0c97954db 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_io_BatchSampler.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_io_BatchSampler.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") o = list(paddle.utils.data.BatchSampler(range(10), batch_size=3, drop_last=True)) print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BCEWithLogitsLoss.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BCEWithLogitsLoss.py index 8b1cbffc5..fb2e5e375 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BCEWithLogitsLoss.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BCEWithLogitsLoss.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") loss = paddle.nn.BCEWithLogitsLoss(reduction="none") input = paddle.tensor([1.0, 0.7, 0.2], requires_grad=True) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py index 5d29e9551..82a582183 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py @@ -1,8 +1,9 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") -paddle.compat.nn.BatchNorm1d(3, eps=0.001, momentum=0.01) +paddle.nn.BatchNorm1d(3, eps=0.001, momentum=0.01) print("#########################case2#########################") -bn = paddle.compat.nn.BatchNorm1d(27) +bn = paddle.nn.BatchNorm1d(27) print("#########################case3#########################") -paddle.compat.nn.BatchNorm1d(10, eps=1e-05, affine=False) +paddle.nn.BatchNorm1d(10, eps=1e-05, affine=False) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py index e5b22eae8..fa50e4089 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py @@ -1,8 +1,9 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") -bn = paddle.compat.nn.BatchNorm2d(5) +bn = paddle.nn.BatchNorm2d(5) print("#########################case2#########################") -bn = paddle.compat.nn.BatchNorm2d(27) +bn = paddle.nn.BatchNorm2d(27) print("#########################case3#########################") -paddle.compat.nn.BatchNorm2d(10, eps=1e-05, affine=False) +paddle.nn.BatchNorm2d(10, eps=1e-05, affine=False) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_InstanceNorm3D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_InstanceNorm3D.py index 2a583c9df..be1645f4d 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_InstanceNorm3D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_InstanceNorm3D.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") m = paddle.nn.InstanceNorm3D(num_features=100) input = paddle.randn(20, 100, 35, 45, 10) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_functional_interpolate.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_functional_interpolate.py index 3ea8841b3..a8fd2004b 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_functional_interpolate.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_functional_interpolate.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.nn.functional.interpolate(paddle.randn(1, 2, 20, 20), [24, 24]) print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_permute.py b/tests/code_library/code_case/paddle_code/api_paddle_permute.py index 4f29c79ab..0be2c69b9 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_permute.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_permute.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") x = paddle.rand([2, 3, 4, 4]) x.permute(0, 2, 3, 1) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_randint.py b/tests/code_library/code_case/paddle_code/api_paddle_randint.py index df404ab02..c37c56d0b 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_randint.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_randint.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.randint(2, 5, [3, 4], device=paddle.device("cuda")) print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/api_paddle_random_manual_seed.py b/tests/code_library/code_case/paddle_code/api_paddle_random_manual_seed.py index 36dd99e87..e340982c2 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_random_manual_seed.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_random_manual_seed.py @@ -1,4 +1,5 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") paddle.manual_seed(23) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_sigmoid.py b/tests/code_library/code_case/paddle_code/api_paddle_sigmoid.py index aeec7f65f..f40c50d5c 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_sigmoid.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_sigmoid.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") t = paddle.randn(4) paddle.sigmoid(t) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_to_tensor.py b/tests/code_library/code_case/paddle_code/api_paddle_to_tensor.py index a0a508514..aa9038911 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_to_tensor.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_to_tensor.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") a = paddle.tensor( paddle.tensor([2, 3, 4]), diff --git a/tests/code_library/code_case/paddle_code/api_paddle_version.py b/tests/code_library/code_case/paddle_code/api_paddle_version.py index 967b882e5..3bac91fd6 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_version.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_version.py @@ -1,3 +1,4 @@ import paddle +paddle.enable_compat(level=2) print(paddle.__version__) diff --git a/tests/code_library/code_case/paddle_code/api_remove_decorator.py b/tests/code_library/code_case/paddle_code/api_remove_decorator.py index 9fe54061b..26c7ce5d6 100644 --- a/tests/code_library/code_case/paddle_code/api_remove_decorator.py +++ b/tests/code_library/code_case/paddle_code/api_remove_decorator.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py b/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py index 10351335a..02842cd43 100644 --- a/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py +++ b/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") data = paddle.tensor([23.0, 32.0, 43.0]) if not data.requires_grad: diff --git a/tests/code_library/code_case/paddle_code/attribute_setattr.py b/tests/code_library/code_case/paddle_code/attribute_setattr.py index 381ae1dba..31c3eca3b 100644 --- a/tests/code_library/code_case/paddle_code/attribute_setattr.py +++ b/tests/code_library/code_case/paddle_code/attribute_setattr.py @@ -1,5 +1,7 @@ import paddle +paddle.enable_compat(level=2) + def add_module(self, name, module): self.add_module(f"{name} - {len(self) + 1}", module) diff --git a/tests/code_library/code_case/paddle_code/attribute_visit_name.py b/tests/code_library/code_case/paddle_code/attribute_visit_name.py index f1b9c1f39..fca18304e 100644 --- a/tests/code_library/code_case/paddle_code/attribute_visit_name.py +++ b/tests/code_library/code_case/paddle_code/attribute_visit_name.py @@ -1,6 +1,8 @@ import paddle import paddleformers +paddle.enable_compat(level=2) + class A(paddle.nn.Module): def __init__(self, data: paddle.Tensor): diff --git a/tests/code_library/code_case/paddle_code/class_method_static_call.py b/tests/code_library/code_case/paddle_code/class_method_static_call.py index 37add8025..c2e1588d2 100644 --- a/tests/code_library/code_case/paddle_code/class_method_static_call.py +++ b/tests/code_library/code_case/paddle_code/class_method_static_call.py @@ -1,5 +1,7 @@ import paddle +paddle.enable_compat(level=2) + class PT_Optimizer(paddle.optimizer.Optimizer): pass diff --git a/tests/code_library/code_case/paddle_code/import_analysis.py b/tests/code_library/code_case/paddle_code/import_analysis.py index 78f0b5776..ba12e70b7 100644 --- a/tests/code_library/code_case/paddle_code/import_analysis.py +++ b/tests/code_library/code_case/paddle_code/import_analysis.py @@ -1,4 +1,3 @@ -import paddle from . import datasets from .datasets import x from yolov3.datasets import a @@ -6,3 +5,6 @@ from .torchvision import x from yolov3.torchvision import a from baidubce.services.bos.bos_client import BosClient +import paddle +import paddle +paddle.enable_compat(level=2) diff --git a/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py b/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py index 40ed1dca0..16d7805f1 100644 --- a/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py +++ b/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py @@ -2,6 +2,7 @@ import paddle +paddle.enable_compat(level=2) if TYPE_CHECKING: pass import warnings diff --git a/tests/code_library/code_case/paddle_code/mark_unsupport.py b/tests/code_library/code_case/paddle_code/mark_unsupport.py index 40407f27f..b6174f2da 100644 --- a/tests/code_library/code_case/paddle_code/mark_unsupport.py +++ b/tests/code_library/code_case/paddle_code/mark_unsupport.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) paddle.add _LOCAL_PROCESS_GROUP = None _MISSING_LOCAL_PG_ERROR = "Local process group is not yet created! Please use detectron2's `launch()` to start processes and initialize pytorch process group. If you need to start processes in other ways, please call comm.create_local_process_group(num_workers_per_machine) after calling torch.distributed.init_process_group()." diff --git a/tests/code_library/code_case/paddle_code/may_paddle_package_list.py b/tests/code_library/code_case/paddle_code/may_paddle_package_list.py index 1ae4ca251..64fbdc993 100644 --- a/tests/code_library/code_case/paddle_code/may_paddle_package_list.py +++ b/tests/code_library/code_case/paddle_code/may_paddle_package_list.py @@ -5,6 +5,7 @@ import setuptools from numpy.random import randint +paddle.enable_compat(level=2) print("#########################case1#########################") paddle.distributed.get_world_size() print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/package_visit_name.py b/tests/code_library/code_case/paddle_code/package_visit_name.py index e8bf8505a..8f73b17ac 100644 --- a/tests/code_library/code_case/paddle_code/package_visit_name.py +++ b/tests/code_library/code_case/paddle_code/package_visit_name.py @@ -1,6 +1,7 @@ import paddle import paddleformers +paddle.enable_compat(level=2) setattr(paddle, "nn", nn_mymodule) hasattr(paddle, "nn") hasattr(paddle, "__version__") diff --git a/tests/code_library/code_case/paddle_code/paddle_llama.py b/tests/code_library/code_case/paddle_code/paddle_llama.py index 20b1adf47..0c18e6b25 100644 --- a/tests/code_library/code_case/paddle_code/paddle_llama.py +++ b/tests/code_library/code_case/paddle_code/paddle_llama.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") model_parallel_size_0 = ( paddle.distributed.fleet.base.topology._HYBRID_PARALLEL_GROUP._mp_degree diff --git a/tests/code_library/code_case/paddle_code/paddlenlp_Qwen.py b/tests/code_library/code_case/paddle_code/paddlenlp_Qwen.py index 8abecc2c3..6ad21c77b 100644 --- a/tests/code_library/code_case/paddle_code/paddlenlp_Qwen.py +++ b/tests/code_library/code_case/paddle_code/paddlenlp_Qwen.py @@ -72,6 +72,7 @@ def _rotate_half(x): ############################## 相关utils函数,如上 ############################## +paddle.enable_compat(level=2) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/simplified_name_call.py b/tests/code_library/code_case/paddle_code/simplified_name_call.py index 88814d982..e6746bdc5 100644 --- a/tests/code_library/code_case/paddle_code/simplified_name_call.py +++ b/tests/code_library/code_case/paddle_code/simplified_name_call.py @@ -1,5 +1,6 @@ import paddle +paddle.enable_compat(level=2) a = paddle.tensor([1]) b = paddle.tensor([2]) print("#########################case1#########################") diff --git a/tests/code_library/code_case/paddle_code/type_hinting.py b/tests/code_library/code_case/paddle_code/type_hinting.py index e3738d091..f74ec5e2b 100644 --- a/tests/code_library/code_case/paddle_code/type_hinting.py +++ b/tests/code_library/code_case/paddle_code/type_hinting.py @@ -2,6 +2,7 @@ import paddle +paddle.enable_compat(level=2) print("#########################case1#########################") Union[Tuple, paddle.BoolTensor] print("#########################case2#########################") From 6bd002d146d4c622f8413d49aad63b030e719ebf Mon Sep 17 00:00:00 2001 From: manfredss Date: Thu, 16 Jul 2026 08:39:57 +0000 Subject: [PATCH 13/34] paddle_package == paddle and add once --- paconvert/transformer/import_transformer.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/paconvert/transformer/import_transformer.py b/paconvert/transformer/import_transformer.py index 1a781b4c6..e2c32eb35 100644 --- a/paconvert/transformer/import_transformer.py +++ b/paconvert/transformer/import_transformer.py @@ -515,14 +515,13 @@ def visit_Module(self, node): paddle_package_list.append(may_torch_package) import_code = "" + enable_compat_code = "" for paddle_package in dict.fromkeys(paddle_package_list): import_code += f"import {paddle_package}\n" + if paddle_package == "paddle": + enable_compat_code = "paddle.enable_compat(level=2)\n" - # Under `paddle.enable_compat(level=2)` the prefix-converted calls - # (torch.X -> paddle.X) resolve to the torch-aligned paddle.compat.* impls, - # so inject it once when `import paddle` is added. isort/black dedupe repeats. - if "paddle" in paddle_package_list: - import_code += "paddle.enable_compat(level=2)\n" + import_code += enable_compat_code if import_code: log_info( @@ -530,9 +529,6 @@ def visit_Module(self, node): f"add '{import_code.strip()}' ", self.file_name, ) - # insert after the module docstring and any surviving (non-torch) - # imports so `enable_compat` lands right below the whole import block; - # isort/black then regroup and dedupe the imports. import_end = 1 if ast.get_docstring(node, clean=False) else 0 while import_end < len(node.body) and isinstance( node.body[import_end], (ast.Import, ast.ImportFrom) From 961af0cedd63fbcfe164acb4fabebc3dc22d5cc6 Mon Sep 17 00:00:00 2001 From: manfredss Date: Mon, 20 Jul 2026 08:15:57 +0000 Subject: [PATCH 14/34] update after paddle changed --- paconvert/api_mapping.json | 21 ++++++++++++------- paconvert/transformer/import_transformer.py | 18 ++++++++++++---- .../minmode_code_case/diff/combine.txt | 14 ++++--------- .../minmode_code_case/diff/keep_same.txt | 12 ++++------- .../paddle_code/api_paddle_nn_BatchNorm1D.py | 6 +++--- .../paddle_code/api_paddle_nn_BatchNorm2D.py | 6 +++--- 6 files changed, 42 insertions(+), 35 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index f7ef51aa9..cb91a9821 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -6160,13 +6160,16 @@ ] }, "torch.nn.AvgPool1d": { - "Matcher": "ChangePrefixMatcher" + "Matcher": "ChangeAPIMatcher", + "paddle_api": "paddle.compat.nn.AvgPool1d" }, "torch.nn.AvgPool2d": { - "Matcher": "ChangePrefixMatcher" + "Matcher": "ChangeAPIMatcher", + "paddle_api": "paddle.compat.nn.AvgPool2d" }, "torch.nn.AvgPool3d": { - "Matcher": "ChangePrefixMatcher" + "Matcher": "ChangeAPIMatcher", + "paddle_api": "paddle.compat.nn.AvgPool3d" }, "torch.nn.BCELoss": { "Matcher": "ChangePrefixMatcher" @@ -6175,13 +6178,16 @@ "Matcher": "ChangePrefixMatcher" }, "torch.nn.BatchNorm1d": { - "Matcher": "ChangePrefixMatcher" + "Matcher": "ChangeAPIMatcher", + "paddle_api": "paddle.compat.nn.BatchNorm1d" }, "torch.nn.BatchNorm2d": { - "Matcher": "ChangePrefixMatcher" + "Matcher": "ChangeAPIMatcher", + "paddle_api": "paddle.compat.nn.BatchNorm2d" }, "torch.nn.BatchNorm3d": { - "Matcher": "ChangePrefixMatcher" + "Matcher": "ChangeAPIMatcher", + "paddle_api": "paddle.compat.nn.BatchNorm3d" }, "torch.nn.Bilinear": { "Matcher": "GenericMatcher", @@ -6793,7 +6799,8 @@ "Matcher": "ChangePrefixMatcher" }, "torch.nn.MultiheadAttention": { - "Matcher": "ChangePrefixMatcher" + "Matcher": "ChangeAPIMatcher", + "paddle_api": "paddle.compat.nn.MultiheadAttention" }, "torch.nn.NLLLoss": { "Matcher": "ChangePrefixMatcher" diff --git a/paconvert/transformer/import_transformer.py b/paconvert/transformer/import_transformer.py index e2c32eb35..d8de085db 100644 --- a/paconvert/transformer/import_transformer.py +++ b/paconvert/transformer/import_transformer.py @@ -530,10 +530,20 @@ def visit_Module(self, node): self.file_name, ) import_end = 1 if ast.get_docstring(node, clean=False) else 0 - while import_end < len(node.body) and isinstance( - node.body[import_end], (ast.Import, ast.ImportFrom) - ): - import_end += 1 + if self.mode == "min": + # import enable_compat before torch is imported. + # jump over __furture__, since it should be right behind docstring + while ( + import_end < len(node.body) + and isinstance(node.body[import_end], (ast.Import, ast.ImportFrom)) + and node.body[import_end].module == "__furture__" + ): + import_end += 1 + else: + while import_end < len(node.body) and isinstance( + node.body[import_end], (ast.Import, ast.ImportFrom) + ): + import_end += 1 self.record_scope( (self.root, "body", import_end), ast.parse(import_code).body ) diff --git a/tests/code_library/code_case/minmode_code_case/diff/combine.txt b/tests/code_library/code_case/minmode_code_case/diff/combine.txt index 3396c8d54..859cc5e7a 100644 --- a/tests/code_library/code_case/minmode_code_case/diff/combine.txt +++ b/tests/code_library/code_case/minmode_code_case/diff/combine.txt @@ -1,21 +1,15 @@ --- /workspace/paconvert/tests/code_library/code_case/minmode_code_case/torch_code/combine.py +++ /workspace/paconvert/tests/code_library/code_case/minmode_code_case/convert_paddle_code/combine.py -@@ -4,6 +4,8 @@ - from collections import OrderedDict - - import numpy as np - - import torch.nn.functional as F - +@@ -1,3 +1,5 @@ +import paddle +paddle.enable_compat(level=2) - print('#########################case1#########################') + import torch - input = torch.tensor([[[[1.1524, 0.4714, 0.2857], [-1.2533, -0.9829, - + import torch.nn as nn - 1.0981], [0.1507, -1.1431, -2.0361]], [[0.1024, -0.4482, 0.4137], [ + from torch.autograd import Function @@ -461,15 +463,15 @@ result = F.softplus(x) diff --git a/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt b/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt index 566d84ef3..f445da44f 100644 --- a/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt +++ b/tests/code_library/code_case/minmode_code_case/diff/keep_same.txt @@ -1,16 +1,12 @@ --- /workspace/paconvert/tests/code_library/code_case/minmode_code_case/torch_code/keep_same.py +++ /workspace/paconvert/tests/code_library/code_case/minmode_code_case/convert_paddle_code/keep_same.py -@@ -1,5 +1,7 @@ - import torch - - import copy - +@@ -1,3 +1,5 @@ +import paddle +paddle.enable_compat(level=2) - print('#########################case1#########################') + import torch - result = torch.BFloat16Tensor([1.5, 2, 3]) + import copy - print('#########################case2#########################') + print('#########################case1#########################') diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py index 82a582183..59a1e3b26 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py @@ -2,8 +2,8 @@ paddle.enable_compat(level=2) print("#########################case1#########################") -paddle.nn.BatchNorm1d(3, eps=0.001, momentum=0.01) +paddle.compat.nn.BatchNorm1d(3, eps=0.001, momentum=0.01) print("#########################case2#########################") -bn = paddle.nn.BatchNorm1d(27) +bn = paddle.compat.nn.BatchNorm1d(27) print("#########################case3#########################") -paddle.nn.BatchNorm1d(10, eps=1e-05, affine=False) +paddle.compat.nn.BatchNorm1d(10, eps=1e-05, affine=False) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py index fa50e4089..faa6b1c6d 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py @@ -2,8 +2,8 @@ paddle.enable_compat(level=2) print("#########################case1#########################") -bn = paddle.nn.BatchNorm2d(5) +bn = paddle.compat.nn.BatchNorm2d(5) print("#########################case2#########################") -bn = paddle.nn.BatchNorm2d(27) +bn = paddle.compat.nn.BatchNorm2d(27) print("#########################case3#########################") -paddle.nn.BatchNorm2d(10, eps=1e-05, affine=False) +paddle.compat.nn.BatchNorm2d(10, eps=1e-05, affine=False) From d8f6e9d357755866408e4a724b5c98ce3db17f6b Mon Sep 17 00:00:00 2001 From: manfredss Date: Wed, 22 Jul 2026 02:25:43 +0000 Subject: [PATCH 15/34] fix --- paconvert/transformer/import_transformer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paconvert/transformer/import_transformer.py b/paconvert/transformer/import_transformer.py index d8de085db..33f0b0515 100644 --- a/paconvert/transformer/import_transformer.py +++ b/paconvert/transformer/import_transformer.py @@ -535,8 +535,8 @@ def visit_Module(self, node): # jump over __furture__, since it should be right behind docstring while ( import_end < len(node.body) - and isinstance(node.body[import_end], (ast.Import, ast.ImportFrom)) - and node.body[import_end].module == "__furture__" + and isinstance(node.body[import_end], ast.ImportFrom) + and node.body[import_end].module == "__future__" ): import_end += 1 else: From 7bb47d134c48e0b65454546d66c8f36d7b6d5225 Mon Sep 17 00:00:00 2001 From: manfredss Date: Wed, 22 Jul 2026 13:01:28 +0000 Subject: [PATCH 16/34] improve --- paconvert/api_mapping.json | 3 +-- tests/conftest.py | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 3f9bf5c20..33dbbfde1 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -4154,8 +4154,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.distributions.Categorical": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.distributions.Categorical" + "Matcher": "ChangePrefixMatcher" }, "torch.distributions.Distribution": { "Matcher": "ChangePrefixMatcher" diff --git a/tests/conftest.py b/tests/conftest.py index a912911b5..6521eed6b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -38,6 +38,9 @@ def disable_paddle_compat(): + if "paddle" not in sys.modules: + return + try: from paddle.compat.proxy import TORCH_PROXY_FINDER except (ImportError, ModuleNotFoundError): From 67be29714cb12f29e6e68e895e5649e9ce0f15b2 Mon Sep 17 00:00:00 2001 From: manfredss Date: Fri, 24 Jul 2026 08:06:59 +0000 Subject: [PATCH 17/34] AvgPool1/2/3d, BatchNorm1/2/3d, MultiheadAttention, Tensor.split to ChangePrefixMathcer. --- paconvert/api_mapping.json | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 33dbbfde1..91b808f71 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -1974,17 +1974,7 @@ "torch.Tensor.sparse_resize_": {}, "torch.Tensor.sparse_resize_and_clear_": {}, "torch.Tensor.split": { - "Matcher": "TensorSplitMatcher", - "paddle_api": "paddle.Tensor.split", - "min_input_args": 1, - "args_list": [ - "split_size", - "dim" - ], - "kwargs_change": { - "split_size": "num_or_sections", - "dim": "axis" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.split_with_sizes": { "Matcher": "ChangePrefixMatcher" @@ -6159,16 +6149,13 @@ ] }, "torch.nn.AvgPool1d": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.AvgPool1d" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.AvgPool2d": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.AvgPool2d" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.AvgPool3d": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.AvgPool3d" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.BCELoss": { "Matcher": "ChangePrefixMatcher" @@ -6177,16 +6164,13 @@ "Matcher": "ChangePrefixMatcher" }, "torch.nn.BatchNorm1d": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.BatchNorm1d" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.BatchNorm2d": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.BatchNorm2d" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.BatchNorm3d": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.BatchNorm3d" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.Bilinear": { "Matcher": "GenericMatcher", @@ -6798,8 +6782,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.nn.MultiheadAttention": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.nn.MultiheadAttention" + "Matcher": "ChangePrefixMatcher" }, "torch.nn.NLLLoss": { "Matcher": "ChangePrefixMatcher" From 9c52c23dd6e3304c96922a3fc8bd52a3589f16f4 Mon Sep 17 00:00:00 2001 From: manfredss Date: Tue, 28 Jul 2026 03:04:45 +0000 Subject: [PATCH 18/34] fix --- paconvert/transformer/import_transformer.py | 20 ++++++------------- scripts/ci/run_cpu_unittest.sh | 7 +++++++ scripts/ci/run_gpu_unittest.sh | 16 +++++++++------ .../paddle_code/api_paddle_nn_BatchNorm1D.py | 6 +++--- .../paddle_code/api_paddle_nn_BatchNorm2D.py | 6 +++--- .../code_case/paddle_code/import_analysis.py | 4 ++-- .../paddle_code/insert_pass_in_ast_if.py | 4 ++-- .../paddle_code/may_paddle_package_list.py | 3 ++- .../code_case/paddle_code/type_hinting.py | 4 ++-- tests/test_optim_lr_scheduler_LRScheduler.py | 1 + tests/torchvision_tests/test_ImageFolder.py | 16 +++++++++------ 11 files changed, 48 insertions(+), 39 deletions(-) diff --git a/paconvert/transformer/import_transformer.py b/paconvert/transformer/import_transformer.py index 33f0b0515..a66865138 100644 --- a/paconvert/transformer/import_transformer.py +++ b/paconvert/transformer/import_transformer.py @@ -530,20 +530,12 @@ def visit_Module(self, node): self.file_name, ) import_end = 1 if ast.get_docstring(node, clean=False) else 0 - if self.mode == "min": - # import enable_compat before torch is imported. - # jump over __furture__, since it should be right behind docstring - while ( - import_end < len(node.body) - and isinstance(node.body[import_end], ast.ImportFrom) - and node.body[import_end].module == "__future__" - ): - import_end += 1 - else: - while import_end < len(node.body) and isinstance( - node.body[import_end], (ast.Import, ast.ImportFrom) - ): - import_end += 1 + while ( + import_end < len(node.body) + and isinstance(node.body[import_end], ast.ImportFrom) + and node.body[import_end].module == "__future__" + ): + import_end += 1 self.record_scope( (self.root, "body", import_end), ast.parse(import_code).body ) diff --git a/scripts/ci/run_cpu_unittest.sh b/scripts/ci/run_cpu_unittest.sh index 5ec27003f..0ed0f6544 100644 --- a/scripts/ci/run_cpu_unittest.sh +++ b/scripts/ci/run_cpu_unittest.sh @@ -48,8 +48,15 @@ PYTEST_IGNORE=( --ignore=tests/test_hub_list.py --ignore=tests/test_hub_load.py --ignore=tests/test_hub_load_state_dict_from_url.py + --ignore=tests/test_set_num_interop_threads.py ) +python -m pytest -v -s -p no:warnings tests/test_set_num_interop_threads.py 2>&1 | tee -a pytest.log +interop_threads_exit=${PIPESTATUS[0]} +if [ ${interop_threads_exit} -ne 0 ]; then + check_errors=${interop_threads_exit} +fi + python -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" --reruns=3 ./tests 2>&1 | tee pytest.log check_errors=${PIPESTATUS[0]} if [ ${check_errors} -ne 0 ]; then diff --git a/scripts/ci/run_gpu_unittest.sh b/scripts/ci/run_gpu_unittest.sh index 213208edf..02949a8b0 100644 --- a/scripts/ci/run_gpu_unittest.sh +++ b/scripts/ci/run_gpu_unittest.sh @@ -40,11 +40,15 @@ echo "Checking code gpu unit test by pytest ..." set +e PYTEST_IGNORE=( + --ignore=tests/test_cuda_stream.py + --ignore=tests/test_cuda_CUDAGraph.py + --ignore=tests/test_cuda_set_stream.py --ignore=tests/test_hub_download_url_to_file.py --ignore=tests/test_hub_help.py --ignore=tests/test_hub_list.py --ignore=tests/test_hub_load.py --ignore=tests/test_hub_load_state_dict_from_url.py + --ignore=tests/test_set_num_interop_threads.py ) # Run test_cuda_stream.py separately and FIRST (GPU state is clean), @@ -64,18 +68,15 @@ cudagraph_exit=${PIPESTATUS[0]} python -m pytest -v -s -p no:warnings tests/test_cuda_set_stream.py 2>&1 | tee -a pytest.log setstream_exit=${PIPESTATUS[0]} +python -m pytest -v -s -p no:warnings tests/test_set_num_interop_threads.py 2>&1 | tee -a pytest.log +interop_threads_exit=${PIPESTATUS[0]} + python -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" \ - --ignore=tests/test_cuda_stream.py \ - --ignore=tests/test_cuda_CUDAGraph.py \ - --ignore=tests/test_cuda_set_stream.py \ -n 1 --reruns=3 ./tests 2>&1 | tee -a pytest.log check_errors=${PIPESTATUS[0]} if [ ${check_errors} -ne 0 ]; then echo "Rerun GPU unit test" python -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" \ - --ignore=tests/test_cuda_stream.py \ - --ignore=tests/test_cuda_CUDAGraph.py \ - --ignore=tests/test_cuda_set_stream.py \ -n 1 --lf ./tests 2>&1 | tee -a pytest.log check_errors=${PIPESTATUS[0]} fi @@ -90,6 +91,9 @@ fi if [ ${setstream_exit} -ne 0 ]; then check_errors=${setstream_exit} fi +if [ ${interop_threads_exit} -ne 0 ]; then + check_errors=${interop_threads_exit} +fi echo '******************************************************************************' if [ ${check_errors} -ne 0 ]; then diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py index 59a1e3b26..82a582183 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm1D.py @@ -2,8 +2,8 @@ paddle.enable_compat(level=2) print("#########################case1#########################") -paddle.compat.nn.BatchNorm1d(3, eps=0.001, momentum=0.01) +paddle.nn.BatchNorm1d(3, eps=0.001, momentum=0.01) print("#########################case2#########################") -bn = paddle.compat.nn.BatchNorm1d(27) +bn = paddle.nn.BatchNorm1d(27) print("#########################case3#########################") -paddle.compat.nn.BatchNorm1d(10, eps=1e-05, affine=False) +paddle.nn.BatchNorm1d(10, eps=1e-05, affine=False) diff --git a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py index faa6b1c6d..fa50e4089 100644 --- a/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py +++ b/tests/code_library/code_case/paddle_code/api_paddle_nn_BatchNorm2D.py @@ -2,8 +2,8 @@ paddle.enable_compat(level=2) print("#########################case1#########################") -bn = paddle.compat.nn.BatchNorm2d(5) +bn = paddle.nn.BatchNorm2d(5) print("#########################case2#########################") -bn = paddle.compat.nn.BatchNorm2d(27) +bn = paddle.nn.BatchNorm2d(27) print("#########################case3#########################") -paddle.compat.nn.BatchNorm2d(10, eps=1e-05, affine=False) +paddle.nn.BatchNorm2d(10, eps=1e-05, affine=False) diff --git a/tests/code_library/code_case/paddle_code/import_analysis.py b/tests/code_library/code_case/paddle_code/import_analysis.py index 224825e00..fc3afd837 100644 --- a/tests/code_library/code_case/paddle_code/import_analysis.py +++ b/tests/code_library/code_case/paddle_code/import_analysis.py @@ -1,3 +1,5 @@ +import paddle +paddle.enable_compat(level=2) from . import datasets from .datasets import x from yolov3.datasets import a @@ -5,5 +7,3 @@ from .torchvision import x from yolov3.torchvision import a from baidubce.services.bos.bos_client import BosClient -import paddle -paddle.enable_compat(level=2) diff --git a/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py b/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py index 16d7805f1..a28d887a0 100644 --- a/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py +++ b/tests/code_library/code_case/paddle_code/insert_pass_in_ast_if.py @@ -1,8 +1,8 @@ -from typing import TYPE_CHECKING - import paddle paddle.enable_compat(level=2) +from typing import TYPE_CHECKING + if TYPE_CHECKING: pass import warnings diff --git a/tests/code_library/code_case/paddle_code/may_paddle_package_list.py b/tests/code_library/code_case/paddle_code/may_paddle_package_list.py index 64fbdc993..e21827267 100644 --- a/tests/code_library/code_case/paddle_code/may_paddle_package_list.py +++ b/tests/code_library/code_case/paddle_code/may_paddle_package_list.py @@ -3,9 +3,10 @@ import einops import paddle import setuptools -from numpy.random import randint paddle.enable_compat(level=2) +from numpy.random import randint + print("#########################case1#########################") paddle.distributed.get_world_size() print("#########################case2#########################") diff --git a/tests/code_library/code_case/paddle_code/type_hinting.py b/tests/code_library/code_case/paddle_code/type_hinting.py index f74ec5e2b..8a8df530f 100644 --- a/tests/code_library/code_case/paddle_code/type_hinting.py +++ b/tests/code_library/code_case/paddle_code/type_hinting.py @@ -1,8 +1,8 @@ -from typing import List, Optional, Tuple, Union - import paddle paddle.enable_compat(level=2) +from typing import List, Optional, Tuple, Union + print("#########################case1#########################") Union[Tuple, paddle.BoolTensor] print("#########################case2#########################") diff --git a/tests/test_optim_lr_scheduler_LRScheduler.py b/tests/test_optim_lr_scheduler_LRScheduler.py index 3d47b0c1d..c9d6d1ea5 100644 --- a/tests/test_optim_lr_scheduler_LRScheduler.py +++ b/tests/test_optim_lr_scheduler_LRScheduler.py @@ -36,6 +36,7 @@ def get_lr(self): loss = parameter.sum() loss.backward() optimizer.step() + scheduler.step() result = parameter result_epoch = scheduler.last_epoch result_is_base = isinstance( diff --git a/tests/torchvision_tests/test_ImageFolder.py b/tests/torchvision_tests/test_ImageFolder.py index 4d45a90e8..dd31fdad2 100644 --- a/tests/torchvision_tests/test_ImageFolder.py +++ b/tests/torchvision_tests/test_ImageFolder.py @@ -30,11 +30,11 @@ def test_case_1(): ) paddle_code = textwrap.dedent( """ - from pathlib import Path - import paddle paddle.enable_compat(level=2) + from pathlib import Path + fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder(root=Path(fake_data_dir)) """ @@ -60,10 +60,11 @@ def test_case_2(): ) paddle_code = textwrap.dedent( """ - import cv2 import paddle paddle.enable_compat(level=2) + import cv2 + fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder( root=fake_data_dir, loader=lambda x: cv2.imread(x), transform=transform @@ -93,10 +94,11 @@ def test_case_3(): ) paddle_code = textwrap.dedent( """ - import cv2 import paddle paddle.enable_compat(level=2) + import cv2 + fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder( root=fake_data_dir, @@ -129,10 +131,11 @@ def test_case_4(): ) paddle_code = textwrap.dedent( """ - import cv2 import paddle paddle.enable_compat(level=2) + import cv2 + fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder( root=fake_data_dir, @@ -165,10 +168,11 @@ def test_case_5(): ) paddle_code = textwrap.dedent( """ - import cv2 import paddle paddle.enable_compat(level=2) + import cv2 + fake_data_dir = "./text_data" image_folder = paddle.vision.datasets.ImageFolder( loader=lambda x: cv2.imread(x), From e39b04228f2c71e009467dcf6c39c582b2bf7c26 Mon Sep 17 00:00:00 2001 From: manfredss Date: Tue, 28 Jul 2026 06:10:09 +0000 Subject: [PATCH 19/34] add fix for split, to help distinguish from string split() and Tensor.split() --- paconvert/api_matcher.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/paconvert/api_matcher.py b/paconvert/api_matcher.py index 9debb3c1a..610006ab6 100644 --- a/paconvert/api_matcher.py +++ b/paconvert/api_matcher.py @@ -392,6 +392,14 @@ def get_paddle_class_attribute_nodes(self, node): return "unchange" def get_paddle_class_nodes(self, func, args, kwargs): + if ( + self.torch_api == "torch.Tensor.split" + and args + and isinstance(args[0], ast.Constant) + and isinstance(args[0].value, str) + ): + return "misidentify" + if self.transformer.mode == "min": self.paddle_api = astor.to_source(func).strip("\n") else: From 8ee2f996b2078d4f2440bb7d8ddaa2338b843345 Mon Sep 17 00:00:00 2001 From: manfredss Date: Thu, 30 Jul 2026 08:03:09 +0000 Subject: [PATCH 20/34] fix --- paconvert/api_matcher.py | 8 --- scripts/ci/run_cpu_unittest.sh | 23 ++++--- scripts/ci/run_gpu_unittest.sh | 50 +++++---------- tests/apibase.py | 77 ++++++++++++++---------- tests/torchvision_tests/model_apibase.py | 19 +----- 5 files changed, 78 insertions(+), 99 deletions(-) diff --git a/paconvert/api_matcher.py b/paconvert/api_matcher.py index 610006ab6..9debb3c1a 100644 --- a/paconvert/api_matcher.py +++ b/paconvert/api_matcher.py @@ -392,14 +392,6 @@ def get_paddle_class_attribute_nodes(self, node): return "unchange" def get_paddle_class_nodes(self, func, args, kwargs): - if ( - self.torch_api == "torch.Tensor.split" - and args - and isinstance(args[0], ast.Constant) - and isinstance(args[0].value, str) - ): - return "misidentify" - if self.transformer.mode == "min": self.paddle_api = astor.to_source(func).strip("\n") else: diff --git a/scripts/ci/run_cpu_unittest.sh b/scripts/ci/run_cpu_unittest.sh index 0ed0f6544..6d12cfa69 100644 --- a/scripts/ci/run_cpu_unittest.sh +++ b/scripts/ci/run_cpu_unittest.sh @@ -38,6 +38,10 @@ echo '************************************************************************** echo "Checking code cpu unit test by pytest ..." set +e +ISOLATED_TESTS=( + tests/test_set_num_interop_threads.py +) + PYTEST_IGNORE=( --ignore=tests/test_backends_cuda_is_built.py --ignore=tests/test_cuda_is_bf16_supported.py @@ -48,16 +52,17 @@ PYTEST_IGNORE=( --ignore=tests/test_hub_list.py --ignore=tests/test_hub_load.py --ignore=tests/test_hub_load_state_dict_from_url.py - --ignore=tests/test_set_num_interop_threads.py ) +for test_file in "${ISOLATED_TESTS[@]}"; do + PYTEST_IGNORE+=(--ignore="${test_file}") +done -python -m pytest -v -s -p no:warnings tests/test_set_num_interop_threads.py 2>&1 | tee -a pytest.log -interop_threads_exit=${PIPESTATUS[0]} -if [ ${interop_threads_exit} -ne 0 ]; then - check_errors=${interop_threads_exit} -fi +python -m pytest -v -s -p no:warnings "${ISOLATED_TESTS[@]}" \ + --reruns=3 2>&1 | tee pytest.log +isolated_errors=${PIPESTATUS[0]} -python -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" --reruns=3 ./tests 2>&1 | tee pytest.log +python -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" \ + --reruns=3 ./tests 2>&1 | tee -a pytest.log check_errors=${PIPESTATUS[0]} if [ ${check_errors} -ne 0 ]; then echo "Rerun CPU unit test" @@ -65,6 +70,10 @@ if [ ${check_errors} -ne 0 ]; then check_errors=${PIPESTATUS[0]} fi +if [ ${isolated_errors} -ne 0 ]; then + check_errors=${isolated_errors} +fi + echo '******************************************************************************' if [ ${check_errors} -ne 0 ]; then echo "Your PR code CPU unit test check FAILED" diff --git a/scripts/ci/run_gpu_unittest.sh b/scripts/ci/run_gpu_unittest.sh index 02949a8b0..789fc7607 100644 --- a/scripts/ci/run_gpu_unittest.sh +++ b/scripts/ci/run_gpu_unittest.sh @@ -39,37 +39,27 @@ echo '************************************************************************** echo "Checking code gpu unit test by pytest ..." set +e +ISOLATED_TESTS=( + tests/test_cuda_stream.py + tests/test_cuda_CUDAGraph.py + tests/test_cuda_set_stream.py + tests/test_set_num_interop_threads.py +) + PYTEST_IGNORE=( - --ignore=tests/test_cuda_stream.py - --ignore=tests/test_cuda_CUDAGraph.py - --ignore=tests/test_cuda_set_stream.py --ignore=tests/test_hub_download_url_to_file.py --ignore=tests/test_hub_help.py --ignore=tests/test_hub_list.py --ignore=tests/test_hub_load.py --ignore=tests/test_hub_load_state_dict_from_url.py - --ignore=tests/test_set_num_interop_threads.py ) +for test_file in "${ISOLATED_TESTS[@]}"; do + PYTEST_IGNORE+=(--ignore="${test_file}") +done -# Run test_cuda_stream.py separately and FIRST (GPU state is clean), -# as it can segfault when run after other GPU tests (Paddle FullKernel issue). -# Running in isolation prevents the segfault from killing the entire test batch. -python -m pytest -v -s -p no:warnings tests/test_cuda_stream.py 2>&1 | tee pytest.log -stream_exit=${PIPESTATUS[0]} - -# Run test_cuda_CUDAGraph.py in its own process as well: CUDA graph -# capture/replay leaves Paddle GPU state that can natively crash later -# AMP tests (e.g. test_cuda_amp_GradScaler) in the same pytest worker. -python -m pytest -v -s -p no:warnings tests/test_cuda_CUDAGraph.py 2>&1 | tee -a pytest.log -cudagraph_exit=${PIPESTATUS[0]} - -# set_stream installs a process-global Paddle stream owned by the temporary exec -# namespace. Run it separately so namespace cleanup cannot poison later GPU tests. -python -m pytest -v -s -p no:warnings tests/test_cuda_set_stream.py 2>&1 | tee -a pytest.log -setstream_exit=${PIPESTATUS[0]} - -python -m pytest -v -s -p no:warnings tests/test_set_num_interop_threads.py 2>&1 | tee -a pytest.log -interop_threads_exit=${PIPESTATUS[0]} +python -m pytest -v -s -p no:warnings "${ISOLATED_TESTS[@]}" \ + -n 1 --reruns=3 2>&1 | tee pytest.log +isolated_errors=${PIPESTATUS[0]} python -m pytest -v -s -p no:warnings "${PYTEST_IGNORE[@]}" \ -n 1 --reruns=3 ./tests 2>&1 | tee -a pytest.log @@ -81,18 +71,8 @@ if [ ${check_errors} -ne 0 ]; then check_errors=${PIPESTATUS[0]} fi -# Propagate isolated test failures if any -if [ ${stream_exit} -ne 0 ]; then - check_errors=${stream_exit} -fi -if [ ${cudagraph_exit} -ne 0 ]; then - check_errors=${cudagraph_exit} -fi -if [ ${setstream_exit} -ne 0 ]; then - check_errors=${setstream_exit} -fi -if [ ${interop_threads_exit} -ne 0 ]; then - check_errors=${interop_threads_exit} +if [ ${isolated_errors} -ne 0 ]; then + check_errors=${isolated_errors} fi echo '******************************************************************************' diff --git a/tests/apibase.py b/tests/apibase.py index 0549843d7..f0d64bfd5 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -16,17 +16,22 @@ import os import re import sys +from contextlib import nullcontext import numpy as np sys.path.append(os.path.dirname(__file__) + "/..") -sys.path.append(os.path.dirname(__file__)) - -from conftest import disable_paddle_compat from paconvert.converter import Converter +def _pytorch_exec_guard(): + paddle = sys.modules.get("paddle") + if paddle is None: + return nullcontext() + return paddle.use_compat_guard(enable=False) + + class APIBase(object): def __init__(self, pytorch_api) -> None: """ @@ -88,55 +93,61 @@ def run( ) assert paddle_code == expect_paddle_code, error_msg elif compared_tensor_names: - disable_paddle_compat() pytorch_ns = {} try: - exec(pytorch_code, pytorch_ns) + with _pytorch_exec_guard(): + exec(pytorch_code, pytorch_ns) except Exception as e: raise RuntimeError(f"Failed to execute pytorch code:\n{e}") pytorch_result = [pytorch_ns[name] for name in compared_tensor_names] pytorch_ns.clear() - paddle_ns = {} - try: - exec(paddle_code, paddle_ns) - except Exception as e: - raise RuntimeError(f"Failed to execute paddle code:\n{e}") - paddle_result = [paddle_ns[name] for name in compared_tensor_names] - paddle_ns.clear() + import paddle - for i in range(len(compared_tensor_names)): + paddle_ns = {} + with paddle.use_compat_guard(level=None): try: - self.compare( - self.pytorch_api, - pytorch_result[i], - paddle_result[i], - check_value, - check_shape, - check_dtype, - check_stop_gradient, - rtol, - atol, - ) + exec(paddle_code, paddle_ns) except Exception as e: - raise AssertionError(f"Unable to align results: {e}") + raise RuntimeError(f"Failed to execute paddle code:\n{e}") + paddle_result = [paddle_ns[name] for name in compared_tensor_names] + paddle_ns.clear() + + for i in range(len(compared_tensor_names)): + try: + self.compare( + self.pytorch_api, + pytorch_result[i], + paddle_result[i], + check_value, + check_shape, + check_dtype, + check_stop_gradient, + rtol, + atol, + ) + except Exception as e: + raise AssertionError(f"Unable to align results: {e}") else: - disable_paddle_compat() pytorch_ns = {} try: - exec(pytorch_code, pytorch_ns) + with _pytorch_exec_guard(): + exec(pytorch_code, pytorch_ns) except Exception as e: raise RuntimeError(f"Failed to execute pytorch code:\n{e}") finally: pytorch_ns.clear() + import paddle + paddle_ns = {} - try: - exec(paddle_code, paddle_ns) - except Exception as e: - raise RuntimeError(f"Failed to execute paddle code:\n{e}") - finally: - paddle_ns.clear() + with paddle.use_compat_guard(level=None): + try: + exec(paddle_code, paddle_ns) + except Exception as e: + raise RuntimeError(f"Failed to execute paddle code:\n{e}") + finally: + paddle_ns.clear() def compare( self, diff --git a/tests/torchvision_tests/model_apibase.py b/tests/torchvision_tests/model_apibase.py index 56814606d..fda30eed1 100644 --- a/tests/torchvision_tests/model_apibase.py +++ b/tests/torchvision_tests/model_apibase.py @@ -12,13 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import numpy as np import paddle import torch from apibase import APIBase -from conftest import disable_paddle_compat class ModelAPIBase(APIBase): @@ -47,17 +44,10 @@ def compare( else: simple_input = np.random.rand(1, 3, 224, 224).astype(np.float32) - # The converted paddle code has globally flipped compat ON (its - # `paddle.enable_compat(level=2)` ran during exec). The torch reference - # forward below must run under REAL torch, otherwise torchvision's - # internal `import torch` / `torch.SymInt` etc. resolve through the - # paddle proxy and blow up. Disable compat for the torch forward, then - # restore it so the paddle forward matches how a user runs the output. - from paddle.compat.proxy import TORCH_PROXY_FINDER + with paddle.use_compat_guard(enable=False): + pytorch_output = pytorch_result(torch.tensor(simple_input)) + paddle_output = paddle_result(paddle.to_tensor(simple_input)) - compat_was_on = TORCH_PROXY_FINDER in sys.meta_path - disable_paddle_compat() - pytorch_output = pytorch_result(torch.tensor(simple_input)) if isinstance(pytorch_output, torch.Tensor): pytorch_numpy = pytorch_output.detach().cpu().numpy() elif isinstance(pytorch_output, tuple): @@ -67,9 +57,6 @@ def compare( else: raise ValueError("Unsupported type for pytorch_output") - if compat_was_on: - paddle.enable_compat(level=2) - paddle_output = paddle_result(paddle.to_tensor(simple_input)) if isinstance(paddle_output, paddle.Tensor): paddle_numpy = paddle_output.detach().numpy() elif isinstance(paddle_output, tuple): From 22d59d63ab02942e66207798fd47f862ab14214b Mon Sep 17 00:00:00 2001 From: manfredss Date: Thu, 30 Jul 2026 08:08:31 +0000 Subject: [PATCH 21/34] delete same conversion param for nn.functional.softmin --- paconvert/api_mapping.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 229eead0e..5060e3d42 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -7810,10 +7810,7 @@ "dtype" ], "kwargs_change": { - "input": "input", - "dim": "dim", - "_stacklevel": "", - "dtype": "dtype" + "_stacklevel": "" }, "min_input_args": 1 }, From 7f11a5406a4b5db63bcbdeb84040bd7e5b04b592 Mon Sep 17 00:00:00 2001 From: manfredss Date: Thu, 30 Jul 2026 08:12:36 +0000 Subject: [PATCH 22/34] enhance three Tensor api tests, enhance Categorical tests, and PReLU tests --- paconvert/api_mapping.json | 30 +-- paconvert/attribute_mapping.json | 3 +- tests/test_Tensor_is_sparse.py | 64 ++++++ tests/test_Tensor_numel.py | 70 ++++++ tests/test_Tensor_type.py | 148 +++++++++++- ...t_distributions_categorical_Categorical.py | 216 ++++++++++++++++++ tests/test_nn_PReLU.py | 65 ++++++ 7 files changed, 562 insertions(+), 34 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 5060e3d42..32199f0a8 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -1692,9 +1692,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.numel": { - "Matcher": "Func2Attribute", - "paddle_api": "paddle.Tensor.size", - "min_input_args": 0 + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.numpy": { "Matcher": "ChangePrefixMatcher" @@ -2182,14 +2180,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.type": { - "Matcher": "TensorTypeMatcher", - "paddle_api": "paddle.Tensor.astype", - "min_input_args": 0, - "args_list": [ - "dtype", - "non_blocking", - "**kwargs" - ] + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.type_as": { "Matcher": "ChangePrefixMatcher" @@ -4218,8 +4209,7 @@ } }, "torch.distributions.categorical.Categorical": { - "Matcher": "ChangeAPIMatcher", - "paddle_api": "paddle.compat.distributions.categorical.Categorical" + "Matcher": "ChangePrefixMatcher" }, "torch.distributions.cauchy.Cauchy": { "Matcher": "GenericMatcher", @@ -6762,19 +6752,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.nn.PReLU": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.nn.PReLU", - "args_list": [ - "num_parameters", - "init", - "device", - "dtype" - ], - "kwargs_change": { - "device": "", - "dtype": "" - }, - "min_input_args": 0 + "Matcher": "ChangePrefixMatcher" }, "torch.nn.PairwiseDistance": { "Matcher": "ChangePrefixMatcher" diff --git a/paconvert/attribute_mapping.json b/paconvert/attribute_mapping.json index 5fc3f259b..b5122271a 100644 --- a/paconvert/attribute_mapping.json +++ b/paconvert/attribute_mapping.json @@ -33,8 +33,7 @@ "torch.Tensor.is_meta": {}, "torch.Tensor.is_quantized": {}, "torch.Tensor.is_sparse": { - "Matcher": "Attribute2Func", - "paddle_api": "paddle.Tensor.is_sparse" + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.is_sparse_csr": { "Matcher": "Attribute2Func", diff --git a/tests/test_Tensor_is_sparse.py b/tests/test_Tensor_is_sparse.py index 6a6ca780c..d16795b36 100644 --- a/tests/test_Tensor_is_sparse.py +++ b/tests/test_Tensor_is_sparse.py @@ -27,3 +27,67 @@ def test_case_1(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_2(): + pytorch_code = textwrap.dedent( + """ + import torch + indices = torch.tensor([[0], [1]]) + values = torch.tensor([1.0]) + a = torch.sparse_coo_tensor(indices, values, [2, 2]) + result = a.is_sparse + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_3(): + pytorch_code = textwrap.dedent( + """ + import torch + crows = torch.tensor([0, 1, 1]) + cols = torch.tensor([0]) + values = torch.tensor([1.0]) + a = torch.sparse_csr_tensor(crows, cols, values, [2, 2]) + result = a.is_sparse + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_4(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.empty([0, 3], dtype=torch.float64) + result = a.is_sparse + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_5(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.arange(24, dtype=torch.int32).reshape(2, 3, 4) + result = a.is_sparse + result_type = type(result).__name__ + """ + ) + obj.run(pytorch_code, ["result", "result_type"]) + + +def test_case_6(): + pytorch_code = textwrap.dedent( + """ + import torch + indices = torch.tensor([[0, 1], [1, 2]]) + values = torch.tensor([1, 2], dtype=torch.int64) + a = torch.sparse_coo_tensor(indices, values, [2, 3]) + result = a.is_sparse + result_type = type(result).__name__ + """ + ) + obj.run(pytorch_code, ["result", "result_type"]) diff --git a/tests/test_Tensor_numel.py b/tests/test_Tensor_numel.py index 907176ce6..1940e3a4d 100644 --- a/tests/test_Tensor_numel.py +++ b/tests/test_Tensor_numel.py @@ -49,3 +49,73 @@ def test_case_3(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_4(): + pytorch_code = textwrap.dedent( + """ + import torch + result = torch.empty(0, 3).numel() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_5(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float64) + count = a.numel() + result = count * 3 + 1 + is_python_int = type(count) is int + """ + ) + obj.run(pytorch_code, ["result", "is_python_int"]) + + +def test_case_6(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.arange(24, dtype=torch.int32).reshape(2, 3, 4) + result = a.numel() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor(7, dtype=torch.int32) + result = a.numel() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + pytorch_code = textwrap.dedent( + """ + import torch + indices = torch.tensor([[0, 1], [1, 2]]) + values = torch.tensor([1.0, 2.0]) + a = torch.sparse_coo_tensor(indices, values, [2, 3]) + result = a.numel() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.ones(2, 3) + args = () + result = a.numel(*args) + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_Tensor_type.py b/tests/test_Tensor_type.py index 14df0a0ef..3fc35e591 100644 --- a/tests/test_Tensor_type.py +++ b/tests/test_Tensor_type.py @@ -60,12 +60,7 @@ def test_case_4(): result = a.type() """ ) - obj.run( - pytorch_code, - ["result"], - check_value=False, - reason="Pytorch return 'torch.FloatTensor' while Paddle rerurn 'paddle.float32' ", - ) + obj.run(pytorch_code, ["result"]) def test_case_5(): @@ -77,3 +72,144 @@ def test_case_5(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.ones(2, 3) + result = a.type("torch.DoubleTensor") + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.ones(2, 3, device="cpu") + result = a.type(dtype=None, non_blocking=False) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.ones(2, 3) + args = (torch.float64, True) + result = a.type(*args) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.ones(2, 3) + kwargs = {"dtype": torch.float64, "non_blocking": True} + result = a.type(**kwargs) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.ones(2, 3) + result = a.type(torch.DoubleTensor) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_11(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.ones(2, 3, device="cpu") + kwargs = {"async": True} + result = a.type(**kwargs) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_12(): + pytorch_code = textwrap.dedent( + """ + import torch + indices = torch.tensor([[0], [1]]) + values = torch.tensor([1.0]) + a = torch.sparse_coo_tensor( + indices, values, [2, 2], device="cpu" + ) + result = a.type() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_13(): + pytorch_code = textwrap.dedent( + """ + import torch + result = [ + torch.ones(1, dtype=torch.bool, device="cpu").type(), + torch.ones(1, dtype=torch.int32, device="cpu").type(), + torch.ones(1, dtype=torch.float64, device="cpu").type(), + torch.ones(1, dtype=torch.bfloat16, device="cpu").type(), + torch.ones(1, dtype=torch.complex64, device="cpu").type(), + ] + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_14(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1.0, 2.0, 3.0], requires_grad=True) + y = a.type(torch.float64) + y.sum().backward() + a_grad = a.grad + """ + ) + obj.run(pytorch_code, ["y", "a_grad"], check_stop_gradient=False) + + +def test_case_15(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.ones(2, 3, device="cpu") + result = ( + a.type(torch.float32) is a, + a.type("torch.FloatTensor") is a, + ) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_16(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.ones(2, 3) + result = [ + a.type("torch.Float8_e4m3fnTensor").type(), + a.type("torch.Float8_e5m2Tensor").type(), + ] + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_distributions_categorical_Categorical.py b/tests/test_distributions_categorical_Categorical.py index 54f3e31f9..67bed9e27 100644 --- a/tests/test_distributions_categorical_Categorical.py +++ b/tests/test_distributions_categorical_Categorical.py @@ -141,3 +141,219 @@ def test_case_11(): """ ) obj.run(pytorch_code, ["result"], check_value=False) + + +def test_case_12(): + """All positional, mixed, and variadic constructor arguments""" + pytorch_code = textwrap.dedent( + """ + import torch + logits = torch.tensor([[0.2, 0.3, 0.5], [1.0, -1.0, 0.5]]) + result1 = torch.distributions.categorical.Categorical(None, logits, False) + result2 = torch.distributions.categorical.Categorical(None, logits=logits, validate_args=False) + args = (None, logits, False) + result3 = torch.distributions.categorical.Categorical(*args) + """ + ) + obj.run(pytorch_code, ["result1", "result2", "result3"]) + + +def test_case_13(): + """Distribution properties and probability methods with batched input""" + pytorch_code = textwrap.dedent( + """ + import torch + probs = torch.tensor([[0.1, 0.3, 0.6], [0.5, 0.2, 0.3]]) + dist = torch.distributions.categorical.Categorical(probs=probs) + value = torch.tensor([2, 0]) + log_prob = dist.log_prob(value) + entropy = dist.entropy() + perplexity = dist.perplexity() + mode = dist.mode + mean_is_nan = torch.isnan(dist.mean) + variance_is_nan = torch.isnan(dist.variance) + param_shape = dist.param_shape + batch_shape = dist.batch_shape + event_shape = dist.event_shape + has_enumerate_support = dist.has_enumerate_support + has_rsample = dist.has_rsample + """ + ) + obj.run( + pytorch_code, + [ + "log_prob", + "entropy", + "perplexity", + "mode", + "mean_is_nan", + "variance_is_nan", + "param_shape", + "batch_shape", + "event_shape", + "has_enumerate_support", + "has_rsample", + ], + ) + + +def test_case_14(): + """Zero probability keeps finite logits and entropy semantics""" + pytorch_code = textwrap.dedent( + """ + import torch + dist = torch.distributions.categorical.Categorical( + probs=torch.tensor([0.0, 0.25, 0.75]) + ) + logits = dist.logits + entropy = dist.entropy() + log_prob = dist.log_prob(torch.tensor([0, 2])) + """ + ) + obj.run(pytorch_code, ["logits", "entropy", "log_prob"]) + + +def test_case_15(): + """Support checks and support enumeration""" + pytorch_code = textwrap.dedent( + """ + import torch + probs = torch.tensor([[0.2, 0.3, 0.5], [0.4, 0.4, 0.2]]) + dist = torch.distributions.categorical.Categorical(probs=probs) + support_check = dist.support.check(torch.tensor([0, 2, -1, 3])) + support_expanded = dist.enumerate_support(expand=True) + support_unexpanded = dist.enumerate_support(expand=False) + """ + ) + obj.run( + pytorch_code, + ["support_check", "support_expanded", "support_unexpanded"], + ) + + +def test_case_16(): + """Expand preserves normalized parameters and distribution shapes""" + pytorch_code = textwrap.dedent( + """ + import torch + logits = torch.tensor([[0.2, 0.3, 0.5], [1.0, -1.0, 0.5]]) + dist = torch.distributions.categorical.Categorical(logits=logits) + result = dist.expand((4, 2)) + expanded_log_prob = result.log_prob(torch.tensor([[0, 1], [1, 2], [2, 0], [0, 2]])) + """ + ) + obj.run(pytorch_code, ["result", "expanded_log_prob"]) + + +def test_case_17(): + """Sample shape, dtype, and support""" + pytorch_code = textwrap.dedent( + """ + import torch + dist = torch.distributions.categorical.Categorical( + probs=torch.tensor([[0.2, 0.8], [0.6, 0.4]]) + ) + samples = dist.sample((2, 3)) + sample_shape = samples.shape + sample_dtype_is_int64 = samples.dtype == torch.int64 + samples_in_support = dist.support.check(samples).all() + """ + ) + obj.run( + pytorch_code, + ["sample_shape", "sample_dtype_is_int64", "samples_in_support"], + ) + + +def test_case_18(): + """Gradient through normalized logits, log_prob, and entropy""" + pytorch_code = textwrap.dedent( + """ + import torch + logits = torch.tensor([0.2, -0.1, 0.7], requires_grad=True) + dist = torch.distributions.categorical.Categorical(logits=logits) + loss = dist.log_prob(torch.tensor(2)) + dist.entropy() + loss.backward() + logits_grad = logits.grad + """ + ) + obj.run( + pytorch_code, + ["loss", "logits_grad"], + check_stop_gradient=False, + rtol=1e-6, + atol=1e-6, + ) + + +def test_case_19(): + """Constructor and sample validation errors""" + pytorch_code = textwrap.dedent( + """ + import torch + errors = [] + try: + torch.distributions.categorical.Categorical() + except ValueError: + errors.append("missing") + try: + torch.distributions.categorical.Categorical( + probs=torch.tensor([0.2, 0.8]), + logits=torch.tensor([0.2, 0.8]), + ) + except ValueError: + errors.append("both") + try: + torch.distributions.categorical.Categorical(torch.tensor(1.0)) + except ValueError: + errors.append("scalar") + dist = torch.distributions.categorical.Categorical( + probs=torch.tensor([0.2, 0.3, 0.5]), + validate_args=True, + ) + try: + dist.log_prob(torch.tensor([3])) + except ValueError: + errors.append("out_of_support") + try: + dist.log_prob(torch.tensor([1.5])) + except ValueError: + errors.append("non_integer") + try: + torch.distributions.categorical.Categorical( + probs=torch.tensor([-0.1, 1.1]), + validate_args=True, + ) + except ValueError: + errors.append("invalid_probs") + try: + torch.distributions.categorical.Categorical( + logits=torch.tensor([float("nan"), 0.0]), + validate_args=True, + ) + except ValueError: + errors.append("invalid_logits") + try: + torch.distributions.categorical.Categorical(torch.empty((0,))) + except ValueError: + errors.append("empty") + """ + ) + obj.run(pytorch_code, ["errors"]) + + +def test_case_20(): + """Integer probabilities and empty categories with validation disabled""" + pytorch_code = textwrap.dedent( + """ + import torch + integer_result = torch.distributions.categorical.Categorical( + probs=torch.tensor([1, 2, 3]) + ) + empty_result = torch.distributions.categorical.Categorical( + probs=torch.empty(0), + validate_args=False, + ) + """ + ) + obj.run(pytorch_code, ["integer_result", "empty_result"]) diff --git a/tests/test_nn_PReLU.py b/tests/test_nn_PReLU.py index d7cd012ee..f177af65d 100644 --- a/tests/test_nn_PReLU.py +++ b/tests/test_nn_PReLU.py @@ -292,3 +292,68 @@ def test_case_18(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_19(): + pytorch_code = textwrap.dedent( + """ + import torch + import torch.nn as nn + x = torch.tensor( + [[[-1.5, 0.5, 2.0], [-0.25, -2.0, 1.0]]], + dtype=torch.float32, + ) + model1 = nn.PReLU(1, 0.3, "cpu") + model2 = nn.PReLU(1, 0.3, "cpu") + result1 = model1(x) + result2 = model2(x) + """ + ) + obj.run(pytorch_code, ["result1", "result2"]) + + +def test_case_20(): + pytorch_code = textwrap.dedent( + """ + import torch + import torch.nn as nn + x = torch.tensor( + [[-2.0, -0.5, 0.75, 1.5]], + dtype=torch.float32, + ) + args = (1, 0.45, "cpu") + model = nn.PReLU(*args) + result = model(x) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_21(): + import importlib + + import paddle + import torch + + class GuardCheckingAPIBase(APIBase): + def compare(self, *args, **kwargs): + result = paddle.sort(paddle.to_tensor([2.0, 1.0]), dim=0) + assert hasattr(result, "values") + return super().compare(*args, **kwargs) + + guard_obj = GuardCheckingAPIBase("torch.nn.PReLU") + native_prelu = paddle.nn.PReLU + native_torch = torch + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[-2.0, -0.5, 0.75, 1.5]]) + result = torch.nn.PReLU(1, 0.45)(x) + """ + ) + + guard_obj.run(pytorch_code, ["result"]) + guard_obj.run(pytorch_code, ["result"]) + + assert paddle.nn.PReLU is native_prelu + assert importlib.import_module("torch") is native_torch From 5362b977d20c4cc4250e88348b3d27665fccc770 Mon Sep 17 00:00:00 2001 From: manfredss Date: Thu, 30 Jul 2026 11:05:58 +0000 Subject: [PATCH 23/34] still fix split typo --- paconvert/api_matcher.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/paconvert/api_matcher.py b/paconvert/api_matcher.py index 9debb3c1a..610006ab6 100644 --- a/paconvert/api_matcher.py +++ b/paconvert/api_matcher.py @@ -392,6 +392,14 @@ def get_paddle_class_attribute_nodes(self, node): return "unchange" def get_paddle_class_nodes(self, func, args, kwargs): + if ( + self.torch_api == "torch.Tensor.split" + and args + and isinstance(args[0], ast.Constant) + and isinstance(args[0].value, str) + ): + return "misidentify" + if self.transformer.mode == "min": self.paddle_api = astor.to_source(func).strip("\n") else: From 1f99f24fce03c372b24e8050b1311da14ee73db0 Mon Sep 17 00:00:00 2001 From: manfredss Date: Fri, 31 Jul 2026 04:01:40 +0000 Subject: [PATCH 24/34] clean --- tests/apibase.py | 4 ++-- tests/conftest.py | 23 ----------------------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/tests/apibase.py b/tests/apibase.py index f0d64bfd5..a2ad73eea 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -105,7 +105,7 @@ def run( import paddle paddle_ns = {} - with paddle.use_compat_guard(level=None): + with paddle.use_compat_guard(enable=False): try: exec(paddle_code, paddle_ns) except Exception as e: @@ -141,7 +141,7 @@ def run( import paddle paddle_ns = {} - with paddle.use_compat_guard(level=None): + with paddle.use_compat_guard(enable=False): try: exec(paddle_code, paddle_ns) except Exception as e: diff --git a/tests/conftest.py b/tests/conftest.py index 6521eed6b..4842d9ffc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -37,27 +37,6 @@ import pytest -def disable_paddle_compat(): - if "paddle" not in sys.modules: - return - - try: - from paddle.compat.proxy import TORCH_PROXY_FINDER - except (ImportError, ModuleNotFoundError): - return - - if TORCH_PROXY_FINDER not in sys.meta_path: - return - - try: - import paddle - - paddle.disable_compat() - except (AttributeError, ImportError, ModuleNotFoundError): - if TORCH_PROXY_FINDER in sys.meta_path: - sys.meta_path.remove(TORCH_PROXY_FINDER) - - def _snapshot_environ(): """Record the process environment so env-var writes can be reverted. @@ -264,7 +243,6 @@ def _reset_global_state(): ``paddle.Tensor`` / ``paddle.nn.*`` classes, and (4) environment variables such as ``CPU_NUM`` written by converted ``set_num_threads`` code. """ - disable_paddle_compat() torch_snap = _snapshot_torch() paddle_snap = _snapshot_paddle() patch_snap = _snapshot_patches() @@ -272,7 +250,6 @@ def _reset_global_state(): try: yield finally: - disable_paddle_compat() _restore_patches(patch_snap) _restore_torch(torch_snap) _restore_paddle(paddle_snap) From d9a9a744da5c3bf23d333d33d1a474cf72b4eacb Mon Sep 17 00:00:00 2001 From: manfredss Date: Fri, 31 Jul 2026 05:57:46 +0000 Subject: [PATCH 25/34] split root cause --- paconvert/api_matcher.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/paconvert/api_matcher.py b/paconvert/api_matcher.py index 610006ab6..b4305628d 100644 --- a/paconvert/api_matcher.py +++ b/paconvert/api_matcher.py @@ -392,18 +392,14 @@ def get_paddle_class_attribute_nodes(self, node): return "unchange" def get_paddle_class_nodes(self, func, args, kwargs): - if ( - self.torch_api == "torch.Tensor.split" - and args - and isinstance(args[0], ast.Constant) - and isinstance(args[0].value, str) - ): - return "misidentify" - if self.transformer.mode == "min": self.paddle_api = astor.to_source(func).strip("\n") else: - self.parse_func(func) + func_str = astor.to_source(func).strip("\n") + paddle_api = self.get_paddle_api() + paddle_class = func_str.rsplit(".", 1)[0] + paddle_class_api = paddle_api.rsplit(".", 1)[0] + self.paddle_api = paddle_api.replace(paddle_class_api, paddle_class, 1) args = self.parse_args(args) kwargs = self.parse_kwargs(kwargs, allow_none=True) From 5cd351e8cdb2b918f13e72d233035b377d9df1a8 Mon Sep 17 00:00:00 2001 From: manfredss Date: Fri, 7 Aug 2026 02:36:47 +0000 Subject: [PATCH 26/34] fix --- paconvert/api_matcher.py | 6 +---- paconvert/base.py | 4 +--- tests/apibase.py | 14 ++--------- tests/test_nn_PReLU.py | 30 ------------------------ tests/torchvision_tests/model_apibase.py | 3 +-- 5 files changed, 5 insertions(+), 52 deletions(-) diff --git a/paconvert/api_matcher.py b/paconvert/api_matcher.py index b4305628d..9debb3c1a 100644 --- a/paconvert/api_matcher.py +++ b/paconvert/api_matcher.py @@ -395,11 +395,7 @@ def get_paddle_class_nodes(self, func, args, kwargs): if self.transformer.mode == "min": self.paddle_api = astor.to_source(func).strip("\n") else: - func_str = astor.to_source(func).strip("\n") - paddle_api = self.get_paddle_api() - paddle_class = func_str.rsplit(".", 1)[0] - paddle_class_api = paddle_api.rsplit(".", 1)[0] - self.paddle_api = paddle_api.replace(paddle_class_api, paddle_class, 1) + self.parse_func(func) args = self.parse_args(args) kwargs = self.parse_kwargs(kwargs, allow_none=True) diff --git a/paconvert/base.py b/paconvert/base.py index a982469a6..31d0a2c73 100644 --- a/paconvert/base.py +++ b/paconvert/base.py @@ -433,9 +433,7 @@ def parse_func(self, func): class_str = "paddle.Tensor|paddle.nn.Module|paddle.optimizer.Optimizer|paddle.optim.Optimizer|paddle.distribution.Distribution|paddle.distributions.distribution.Distribution|paddle.autograd.function.FunctionCtx|paddle.profiler.Profiler" if self.get_paddle_api(): new_paddle_api = re.sub( - class_str, - re.escape(self.paddleClass), - self.get_paddle_api(), + class_str, lambda m: self.paddleClass, self.get_paddle_api(), count=1 ) # reverse escape new_paddle_api = re.sub(r"\\(.)", r"\1", new_paddle_api) diff --git a/tests/apibase.py b/tests/apibase.py index a2ad73eea..8d5d342de 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -16,7 +16,6 @@ import os import re import sys -from contextlib import nullcontext import numpy as np @@ -25,13 +24,6 @@ from paconvert.converter import Converter -def _pytorch_exec_guard(): - paddle = sys.modules.get("paddle") - if paddle is None: - return nullcontext() - return paddle.use_compat_guard(enable=False) - - class APIBase(object): def __init__(self, pytorch_api) -> None: """ @@ -95,8 +87,7 @@ def run( elif compared_tensor_names: pytorch_ns = {} try: - with _pytorch_exec_guard(): - exec(pytorch_code, pytorch_ns) + exec(pytorch_code, pytorch_ns) except Exception as e: raise RuntimeError(f"Failed to execute pytorch code:\n{e}") pytorch_result = [pytorch_ns[name] for name in compared_tensor_names] @@ -131,8 +122,7 @@ def run( else: pytorch_ns = {} try: - with _pytorch_exec_guard(): - exec(pytorch_code, pytorch_ns) + exec(pytorch_code, pytorch_ns) except Exception as e: raise RuntimeError(f"Failed to execute pytorch code:\n{e}") finally: diff --git a/tests/test_nn_PReLU.py b/tests/test_nn_PReLU.py index f177af65d..137c64aef 100644 --- a/tests/test_nn_PReLU.py +++ b/tests/test_nn_PReLU.py @@ -327,33 +327,3 @@ def test_case_20(): """ ) obj.run(pytorch_code, ["result"]) - - -def test_case_21(): - import importlib - - import paddle - import torch - - class GuardCheckingAPIBase(APIBase): - def compare(self, *args, **kwargs): - result = paddle.sort(paddle.to_tensor([2.0, 1.0]), dim=0) - assert hasattr(result, "values") - return super().compare(*args, **kwargs) - - guard_obj = GuardCheckingAPIBase("torch.nn.PReLU") - native_prelu = paddle.nn.PReLU - native_torch = torch - pytorch_code = textwrap.dedent( - """ - import torch - x = torch.tensor([[-2.0, -0.5, 0.75, 1.5]]) - result = torch.nn.PReLU(1, 0.45)(x) - """ - ) - - guard_obj.run(pytorch_code, ["result"]) - guard_obj.run(pytorch_code, ["result"]) - - assert paddle.nn.PReLU is native_prelu - assert importlib.import_module("torch") is native_torch diff --git a/tests/torchvision_tests/model_apibase.py b/tests/torchvision_tests/model_apibase.py index fda30eed1..c3ee9f397 100644 --- a/tests/torchvision_tests/model_apibase.py +++ b/tests/torchvision_tests/model_apibase.py @@ -44,8 +44,7 @@ def compare( else: simple_input = np.random.rand(1, 3, 224, 224).astype(np.float32) - with paddle.use_compat_guard(enable=False): - pytorch_output = pytorch_result(torch.tensor(simple_input)) + pytorch_output = pytorch_result(torch.tensor(simple_input)) paddle_output = paddle_result(paddle.to_tensor(simple_input)) if isinstance(pytorch_output, torch.Tensor): From 770552a363d8cca448708c75f1b92192fe090db9 Mon Sep 17 00:00:00 2001 From: manfredss Date: Fri, 7 Aug 2026 03:35:51 +0000 Subject: [PATCH 27/34] add reason for check_value=False --- tests/test_Tensor_type.py | 42 +++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/tests/test_Tensor_type.py b/tests/test_Tensor_type.py index 3fc35e591..b844c96f4 100644 --- a/tests/test_Tensor_type.py +++ b/tests/test_Tensor_type.py @@ -60,7 +60,12 @@ def test_case_4(): result = a.type() """ ) - obj.run(pytorch_code, ["result"]) + obj.run( + pytorch_code, + ["result"], + check_value=False, + reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", + ) def test_case_5(): @@ -93,7 +98,12 @@ def test_case_7(): result = a.type(dtype=None, non_blocking=False) """ ) - obj.run(pytorch_code, ["result"]) + obj.run( + pytorch_code, + ["result"], + check_value=False, + reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", + ) def test_case_8(): @@ -140,7 +150,12 @@ def test_case_11(): result = a.type(**kwargs) """ ) - obj.run(pytorch_code, ["result"]) + obj.run( + pytorch_code, + ["result"], + check_value=False, + reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", + ) def test_case_12(): @@ -155,7 +170,12 @@ def test_case_12(): result = a.type() """ ) - obj.run(pytorch_code, ["result"]) + obj.run( + pytorch_code, + ["result"], + check_value=False, + reason="Pytorch return 'torch.sparse.FloatTensor' while Paddle return 'paddle.float32', which does not encode the sparse layout", + ) def test_case_13(): @@ -171,7 +191,12 @@ def test_case_13(): ] """ ) - obj.run(pytorch_code, ["result"]) + obj.run( + pytorch_code, + ["result"], + check_value=False, + reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", + ) def test_case_14(): @@ -212,4 +237,9 @@ def test_case_16(): ] """ ) - obj.run(pytorch_code, ["result"]) + obj.run( + pytorch_code, + ["result"], + check_value=False, + reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", + ) From 38925e2d4fa6377547cf1a6b8bf529db9bf6bd89 Mon Sep 17 00:00:00 2001 From: manfredss Date: Fri, 7 Aug 2026 07:28:00 +0000 Subject: [PATCH 28/34] fix backslash --- paconvert/base.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/paconvert/base.py b/paconvert/base.py index 31d0a2c73..361cdf0bf 100644 --- a/paconvert/base.py +++ b/paconvert/base.py @@ -435,8 +435,6 @@ def parse_func(self, func): new_paddle_api = re.sub( class_str, lambda m: self.paddleClass, self.get_paddle_api(), count=1 ) - # reverse escape - new_paddle_api = re.sub(r"\\(.)", r"\1", new_paddle_api) self.paddle_api = new_paddle_api def args_to_str(self, args): From 9091b39b33102b3cf8f5634bc271f2393cf92210 Mon Sep 17 00:00:00 2001 From: manfredss Date: Mon, 10 Aug 2026 12:08:54 +0000 Subject: [PATCH 29/34] use paddle.compat.split rather than paddle.tensor.split, since enable_compat(level=2) in use --- paconvert/api_matcher.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/paconvert/api_matcher.py b/paconvert/api_matcher.py index 9debb3c1a..8bedabed2 100644 --- a/paconvert/api_matcher.py +++ b/paconvert/api_matcher.py @@ -5799,9 +5799,7 @@ def reduce_scatter_tensor(output, input, op, group, async_op): if input.shape[0] == world_size: input_list = paddle.unstack(input, axis=0) else: - input_list = paddle.tensor.split( - input, num_or_sections=world_size, axis=0 - ) + input_list = paddle.compat.split(input, world_size, dim=0) paddle.distributed.reduce_scatter(output, input_list, op, group, async_op) """ ) From 9472d8e8fee137ca1a4585046468762608af2990 Mon Sep 17 00:00:00 2001 From: manfredss Date: Wed, 12 Aug 2026 02:08:45 +0000 Subject: [PATCH 30/34] move the logic into apibase and remove conftest.py; adjust other files that could affect running env --- scripts/ci/run_gpu_unittest.sh | 4 + tests/apibase.py | 111 ++++++++++++-- tests/conftest.py | 256 ------------------------------- tests/test_get_default_device.py | 1 + tests/test_set_default_device.py | 6 + tests/test_set_grad_enabled.py | 1 + 6 files changed, 106 insertions(+), 273 deletions(-) delete mode 100644 tests/conftest.py diff --git a/scripts/ci/run_gpu_unittest.sh b/scripts/ci/run_gpu_unittest.sh index 789fc7607..bab55b7e5 100644 --- a/scripts/ci/run_gpu_unittest.sh +++ b/scripts/ci/run_gpu_unittest.sh @@ -43,6 +43,10 @@ ISOLATED_TESTS=( tests/test_cuda_stream.py tests/test_cuda_CUDAGraph.py tests/test_cuda_set_stream.py + tests/test_cpu_set_device.py + tests/test_set_default_device.py + tests/test_get_default_device.py + tests/test_set_num_threads.py tests/test_set_num_interop_threads.py ) diff --git a/tests/apibase.py b/tests/apibase.py index 8d5d342de..0a005aeb3 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -23,6 +23,74 @@ from paconvert.converter import Converter +_SENTINEL = object() + + +def _patch_targets(paddle): + """Global paddle classes that converted code monkeypatches via ``setattr``. + + Converted code frequently ends with e.g. + ``setattr(paddle.Tensor, "add", _Tensor_add)`` or + ``setattr(paddle.nn.LogSoftmax, "forward", _log_softmax_forward)``, where the + helper is defined in the exec namespace. The patch lands on the *global* + class, so without restoring it the next test keeps running against the + previous test's implementation. + """ + targets = [paddle.Tensor] + nn = getattr(paddle, "nn", None) + if nn is not None: + for name in dir(nn): + obj = getattr(nn, name, None) + if isinstance(obj, type): + targets.append(obj) + return targets + + +def _snapshot_patches(paddle): + snap = [] + for target in _patch_targets(paddle): + try: + snap.append((target, dict(vars(target)))) + except TypeError: + continue + return snap + + +def _is_compat_owned(obj): + """Whether ``obj`` was installed by ``paddle.enable_compat``, not by a test. + + ``paddle.compat`` installs caller-aware dispatchers that carry + ``__compat_fn__``/``__native_fn__`` (see ``paddle/compat/api_dispatch.py``) + and keeps its own bookkeeping of what it replaced. Reverting those behind + paddle's back leaves it unable to reinstall them, so they must be left + alone; only plain helpers set by the converted code are ours to clean up. + """ + return hasattr(obj, "__compat_fn__") or hasattr(obj, "__native_fn__") + + +def _restore_patches(snap): + """Revert only the attributes the exec'd code added or replaced.""" + for target, attrs in snap: + try: + current = dict(vars(target)) + except TypeError: + continue + for name, original in attrs.items(): + now = current.get(name, _SENTINEL) + if now is original or _is_compat_owned(now): + continue + try: + setattr(target, name, original) + except (AttributeError, TypeError): + pass + for name, now in current.items(): + if name in attrs or _is_compat_owned(now): + continue + try: + delattr(target, name) + except (AttributeError, TypeError): + pass + class APIBase(object): def __init__(self, pytorch_api) -> None: @@ -97,28 +165,35 @@ def run( paddle_ns = {} with paddle.use_compat_guard(enable=False): + patch_snap = _snapshot_patches(paddle) try: exec(paddle_code, paddle_ns) except Exception as e: raise RuntimeError(f"Failed to execute paddle code:\n{e}") paddle_result = [paddle_ns[name] for name in compared_tensor_names] - paddle_ns.clear() - - for i in range(len(compared_tensor_names)): - try: - self.compare( - self.pytorch_api, - pytorch_result[i], - paddle_result[i], - check_value, - check_shape, - check_dtype, - check_stop_gradient, - rtol, - atol, - ) - except Exception as e: - raise AssertionError(f"Unable to align results: {e}") + + try: + for i in range(len(compared_tensor_names)): + try: + self.compare( + self.pytorch_api, + pytorch_result[i], + paddle_result[i], + check_value, + check_shape, + check_dtype, + check_stop_gradient, + rtol, + atol, + ) + except Exception as e: + raise AssertionError(f"Unable to align results: {e}") + finally: + # The converted code patches global paddle classes with + # helpers defined in ``paddle_ns``; revert them so the next + # test does not run against this test's implementations. + _restore_patches(patch_snap) + paddle_ns.clear() else: pytorch_ns = {} try: @@ -132,11 +207,13 @@ def run( paddle_ns = {} with paddle.use_compat_guard(enable=False): + patch_snap = _snapshot_patches(paddle) try: exec(paddle_code, paddle_ns) except Exception as e: raise RuntimeError(f"Failed to execute paddle code:\n{e}") finally: + _restore_patches(patch_snap) paddle_ns.clear() def compare( diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index 4842d9ffc..000000000 --- a/tests/conftest.py +++ /dev/null @@ -1,256 +0,0 @@ -# Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved. -# -# 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. - -"""Global-state isolation for the test suite. - -Each test execs both a torch reference and the converted paddle code in the SAME -worker process (see ``tests/apibase.py``). Process-global switches such as -``torch.set_default_device('cuda')``, ``set_default_dtype`` or the grad-enabled -flag therefore LEAK into every later test in that process, causing failures that -only appear in the full suite (and vanish on a ``--lf`` rerun that no longer -schedules the polluting test first). - -The autouse fixture below snapshots that global state before each test and -restores it afterwards, so a test that forgets to reset (e.g. -``torch.set_default_device('cuda:0')`` with no matching reset) can no longer -corrupt its neighbours. - -The logic is lazy and best-effort: it only touches a framework that is already in -``sys.modules``, so it never forces an import of torch/paddle (which would change -import ordering) for tests that don't use them. -""" - -import os -import sys - -import pytest - - -def _snapshot_environ(): - """Record the process environment so env-var writes can be reverted. - - Converted code maps some torch APIs to environment variables, e.g. - ``torch.set_num_threads(n)`` -> ``os.environ['CPU_NUM'] = str(n)``. Left set, - that leaks into ``torch.get_num_threads`` -> ``os.getenv('CPU_NUM', 1)`` in a - later test, which then returns a ``str`` instead of the default ``int``. - """ - return dict(os.environ) - - -def _restore_environ(snap): - for key in list(os.environ.keys()): - if key not in snap: - try: - del os.environ[key] - except Exception: - pass - for key, value in snap.items(): - if os.environ.get(key) != value: - try: - os.environ[key] = value - except Exception: - pass - - -def _snapshot_torch(): - torch = sys.modules.get("torch") - if torch is None: - return None - context_holder = torch._GLOBAL_DEVICE_CONTEXT - if getattr(context_holder, "device_context", False) is None: - del context_holder.device_context - snap = {} - try: - snap["dtype"] = torch.get_default_dtype() - except Exception: - pass - try: - snap["device"] = torch.get_default_device() - snap["has_device_context"] = hasattr( - torch._GLOBAL_DEVICE_CONTEXT, "device_context" - ) - except Exception: - pass - try: - snap["grad"] = torch.is_grad_enabled() - except Exception: - pass - return snap - - -def _restore_torch(snap): - torch = sys.modules.get("torch") - if torch is None: - return - dtype = torch.float32 - device = "cpu" - grad = True - if snap: - dtype = snap.get("dtype", dtype) - device = snap.get("device", device) - grad = snap.get("grad", grad) - try: - torch.set_default_dtype(dtype) - except Exception: - pass - try: - context_holder = torch._GLOBAL_DEVICE_CONTEXT - current_context = getattr(context_holder, "device_context", None) - if current_context is not None: - current_context.__exit__(None, None, None) - if hasattr(context_holder, "device_context"): - del context_holder.device_context - if snap and snap.get("has_device_context"): - torch.set_default_device(device) - except Exception: - pass - try: - torch.set_grad_enabled(grad) - except Exception: - pass - - -def _snapshot_paddle(): - paddle = sys.modules.get("paddle") - if paddle is None: - return None - snap = {} - try: - snap["dtype"] = paddle.get_default_dtype() - except Exception: - pass - try: - snap["device"] = paddle.device.get_device() - except Exception: - pass - try: - snap["grad"] = paddle.is_grad_enabled() - except Exception: - pass - return snap - - -def _restore_paddle(snap): - paddle = sys.modules.get("paddle") - if paddle is None or not snap: - return - if "dtype" in snap: - try: - paddle.set_default_dtype(snap["dtype"]) - except Exception: - pass - if "device" in snap: - try: - paddle.device.set_device(snap["device"]) - except Exception: - pass - if "grad" in snap: - try: - paddle.set_grad_enabled(snap["grad"]) - except Exception: - pass - - -_SENTINEL = object() - - -def _patch_targets(): - """Global paddle objects that converted code monkeypatches via ``setattr``. - - Converted paddle code frequently does e.g. - ``setattr(paddle.Tensor, "add", _add)`` or - ``setattr(paddle.nn.LogSoftmax, "forward", _log_softmax_forward)`` where the - helper is defined in the exec namespace. Because the patch lands on the - *global* class it leaks into every later test; and because ``apibase`` clears - the exec namespace afterwards, the helper's ``__globals__`` is emptied, so a - later call raises ``NameError: name 'paddle' is not defined``. - - We return ``paddle.Tensor`` plus every class exposed on ``paddle.nn`` so the - fixture can snapshot their attributes and revert any test-induced change. - """ - paddle = sys.modules.get("paddle") - if paddle is None: - return [] - targets = [] - tensor = getattr(paddle, "Tensor", None) - if tensor is not None: - targets.append(tensor) - nn = getattr(paddle, "nn", None) - if nn is not None: - for name in dir(nn): - try: - obj = getattr(nn, name) - except Exception: - continue - if isinstance(obj, type): - targets.append(obj) - return targets - - -def _snapshot_patches(): - """Record current attribute values of monkeypatchable paddle targets.""" - snap = [] - for target in _patch_targets(): - try: - attrs = dict(vars(target)) - except TypeError: - continue - snap.append((target, attrs)) - return snap - - -def _restore_patches(snap): - """Revert only the attributes a test added or replaced on paddle targets.""" - for target, attrs in snap: - try: - current = dict(vars(target)) - except TypeError: - continue - # Restore attributes whose object identity changed during the test. - for name, original in attrs.items(): - if current.get(name, _SENTINEL) is not original: - try: - setattr(target, name, original) - except (AttributeError, TypeError): - pass - # Delete attributes that the test added and that were not present before. - for name in current: - if name not in attrs: - try: - delattr(target, name) - except (AttributeError, TypeError): - pass - - -@pytest.fixture(autouse=True) -def _reset_global_state(): - """Snapshot and restore torch/paddle process-global state around each test. - - Covers the classes of cross-test pollution that only surface in the full - suite (and vanish on ``--lf``): (1) torch/paddle default device, (2) default - dtype and grad mode, (3) global monkeypatches converted code applies to - ``paddle.Tensor`` / ``paddle.nn.*`` classes, and (4) environment variables - such as ``CPU_NUM`` written by converted ``set_num_threads`` code. - """ - torch_snap = _snapshot_torch() - paddle_snap = _snapshot_paddle() - patch_snap = _snapshot_patches() - environ_snap = _snapshot_environ() - try: - yield - finally: - _restore_patches(patch_snap) - _restore_torch(torch_snap) - _restore_paddle(paddle_snap) - _restore_environ(environ_snap) diff --git a/tests/test_get_default_device.py b/tests/test_get_default_device.py index 94e89d22c..819ad5a7c 100644 --- a/tests/test_get_default_device.py +++ b/tests/test_get_default_device.py @@ -59,6 +59,7 @@ def test_case_3(): import torch torch.set_default_device(device=torch.device("cuda:0")) result = torch.get_default_device() + torch.set_default_device(None) """ ) obj.run(pytorch_code, ["result"]) diff --git a/tests/test_set_default_device.py b/tests/test_set_default_device.py index 3c5e1c518..2aa0e3bbd 100644 --- a/tests/test_set_default_device.py +++ b/tests/test_set_default_device.py @@ -178,6 +178,7 @@ def test_case_9(): device = "cuda:0" torch.set_default_device(device=device) result = torch.get_default_device() + torch.set_default_device(None) """ ) obj.run(pytorch_code, ["result"]) @@ -209,6 +210,7 @@ def test_case_11(): cond = True torch.set_default_device(device='cuda' if cond else 'cpu') result = torch.get_default_device() + torch.set_default_device(None) """ ) obj.run(pytorch_code, ["result"]) @@ -225,6 +227,7 @@ def test_case_12(): cond = True torch.set_default_device(device='cuda:0' if cond else 'cuda:1') result = torch.get_default_device() + torch.set_default_device(None) """ ) obj.run(pytorch_code, ["result"]) @@ -262,6 +265,7 @@ def test_case_14(): device = "cuda:0" if cond else "cuda:1" torch.set_default_device(device=device) result = torch.get_default_device() + torch.set_default_device(None) """ ) obj.run(pytorch_code, ["result"]) @@ -277,6 +281,7 @@ def test_case_15(): import torch torch.set_default_device(0) result = torch.get_default_device() + torch.set_default_device(None) """ ) obj.run(pytorch_code, ["result"]) @@ -293,6 +298,7 @@ def test_case_16(): cond = True torch.set_default_device(device=0 if False else 1) result = torch.get_default_device() + torch.set_default_device(None) """ ) obj.run(pytorch_code, ["result"]) diff --git a/tests/test_set_grad_enabled.py b/tests/test_set_grad_enabled.py index 0dd9d27c8..3981fa203 100644 --- a/tests/test_set_grad_enabled.py +++ b/tests/test_set_grad_enabled.py @@ -53,6 +53,7 @@ def test_case_3(): x = torch.tensor([1.], requires_grad=True) _ = torch.set_grad_enabled(False) result = x * 2 + torch.set_grad_enabled(True) """ ) obj.run(pytorch_code, ["result"]) From 92a46973aa40d7c501ea8c1711a30db47626cac4 Mon Sep 17 00:00:00 2001 From: manfredss Date: Wed, 12 Aug 2026 12:38:16 +0000 Subject: [PATCH 31/34] simplify logic --- tests/apibase.py | 48 +++++++++++++----------------------------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/tests/apibase.py b/tests/apibase.py index 0a005aeb3..30fca1c56 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -26,15 +26,11 @@ _SENTINEL = object() -def _patch_targets(paddle): - """Global paddle classes that converted code monkeypatches via ``setattr``. - - Converted code frequently ends with e.g. - ``setattr(paddle.Tensor, "add", _Tensor_add)`` or - ``setattr(paddle.nn.LogSoftmax, "forward", _log_softmax_forward)``, where the - helper is defined in the exec namespace. The patch lands on the *global* - class, so without restoring it the next test keeps running against the - previous test's implementation. +def _snapshot_patches(paddle): + """Snapshot paddle classes that converted code patches via ``setattr``. + + The helper is defined in the exec namespace but the patch lands on the + global class, so it must be reverted after each test. """ targets = [paddle.Tensor] nn = getattr(paddle, "nn", None) @@ -43,27 +39,18 @@ def _patch_targets(paddle): obj = getattr(nn, name, None) if isinstance(obj, type): targets.append(obj) - return targets - -def _snapshot_patches(paddle): snap = [] - for target in _patch_targets(paddle): - try: - snap.append((target, dict(vars(target)))) - except TypeError: - continue + for target in targets: + snap.append((target, dict(vars(target)))) return snap def _is_compat_owned(obj): - """Whether ``obj`` was installed by ``paddle.enable_compat``, not by a test. + """Whether ``obj`` is a ``paddle.enable_compat`` dispatcher rather than a test patch. - ``paddle.compat`` installs caller-aware dispatchers that carry - ``__compat_fn__``/``__native_fn__`` (see ``paddle/compat/api_dispatch.py``) - and keeps its own bookkeeping of what it replaced. Reverting those behind - paddle's back leaves it unable to reinstall them, so they must be left - alone; only plain helpers set by the converted code are ours to clean up. + Compat keeps its own list of what it replaced, so reverting these behind + paddle's back leaves it unable to reinstall them. """ return hasattr(obj, "__compat_fn__") or hasattr(obj, "__native_fn__") @@ -71,25 +58,16 @@ def _is_compat_owned(obj): def _restore_patches(snap): """Revert only the attributes the exec'd code added or replaced.""" for target, attrs in snap: - try: - current = dict(vars(target)) - except TypeError: - continue + current = dict(vars(target)) for name, original in attrs.items(): now = current.get(name, _SENTINEL) if now is original or _is_compat_owned(now): continue - try: - setattr(target, name, original) - except (AttributeError, TypeError): - pass + setattr(target, name, original) for name, now in current.items(): if name in attrs or _is_compat_owned(now): continue - try: - delattr(target, name) - except (AttributeError, TypeError): - pass + delattr(target, name) class APIBase(object): From fa9523eb91052550aea5f9bb971a899fb502e77b Mon Sep 17 00:00:00 2001 From: manfredss Date: Thu, 13 Aug 2026 06:30:34 +0000 Subject: [PATCH 32/34] manage context, especially for paddle.nn.Softmin --- tests/apibase.py | 18 ++++++--- tests/test_Tensor_type.py | 79 ++++++++++++++++----------------------- 2 files changed, 45 insertions(+), 52 deletions(-) diff --git a/tests/apibase.py b/tests/apibase.py index 30fca1c56..b744a356e 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import contextlib import difflib import os import re @@ -70,6 +71,16 @@ def _restore_patches(snap): delattr(target, name) +@contextlib.contextmanager +def _compat_disabled(paddle): + """Run the block with compat off, and leave it off afterwards.""" + paddle.disable_compat() + try: + yield + finally: + paddle.disable_compat() + + class APIBase(object): def __init__(self, pytorch_api) -> None: """ @@ -142,7 +153,7 @@ def run( import paddle paddle_ns = {} - with paddle.use_compat_guard(enable=False): + with _compat_disabled(paddle): patch_snap = _snapshot_patches(paddle) try: exec(paddle_code, paddle_ns) @@ -167,9 +178,6 @@ def run( except Exception as e: raise AssertionError(f"Unable to align results: {e}") finally: - # The converted code patches global paddle classes with - # helpers defined in ``paddle_ns``; revert them so the next - # test does not run against this test's implementations. _restore_patches(patch_snap) paddle_ns.clear() else: @@ -184,7 +192,7 @@ def run( import paddle paddle_ns = {} - with paddle.use_compat_guard(enable=False): + with _compat_disabled(paddle): patch_snap = _snapshot_patches(paddle) try: exec(paddle_code, paddle_ns) diff --git a/tests/test_Tensor_type.py b/tests/test_Tensor_type.py index b844c96f4..48e439bae 100644 --- a/tests/test_Tensor_type.py +++ b/tests/test_Tensor_type.py @@ -57,15 +57,12 @@ def test_case_4(): """ import torch a = torch.Tensor([1,2,3]) - result = a.type() + # paddle returns paddle.FloatTensor etc, so drop the namespace + # prefix and compare the remaining segments + result = a.type().split(".", 1)[1] """ ) - obj.run( - pytorch_code, - ["result"], - check_value=False, - reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", - ) + obj.run(pytorch_code, ["result"]) def test_case_5(): @@ -95,15 +92,12 @@ def test_case_7(): """ import torch a = torch.ones(2, 3, device="cpu") - result = a.type(dtype=None, non_blocking=False) + # paddle returns paddle.FloatTensor etc, so drop the namespace + # prefix and compare the remaining segments + result = a.type(dtype=None, non_blocking=False).split(".", 1)[1] """ ) - obj.run( - pytorch_code, - ["result"], - check_value=False, - reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", - ) + obj.run(pytorch_code, ["result"]) def test_case_8(): @@ -147,15 +141,12 @@ def test_case_11(): import torch a = torch.ones(2, 3, device="cpu") kwargs = {"async": True} - result = a.type(**kwargs) + # paddle returns paddle.FloatTensor etc, so drop the namespace + # prefix and compare the remaining segments + result = a.type(**kwargs).split(".", 1)[1] """ ) - obj.run( - pytorch_code, - ["result"], - check_value=False, - reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", - ) + obj.run(pytorch_code, ["result"]) def test_case_12(): @@ -167,36 +158,33 @@ def test_case_12(): a = torch.sparse_coo_tensor( indices, values, [2, 2], device="cpu" ) - result = a.type() + # paddle returns paddle.FloatTensor etc, so drop the namespace + # prefix and compare the remaining segments + result = a.type().split(".", 1)[1] """ ) - obj.run( - pytorch_code, - ["result"], - check_value=False, - reason="Pytorch return 'torch.sparse.FloatTensor' while Paddle return 'paddle.float32', which does not encode the sparse layout", - ) + obj.run(pytorch_code, ["result"]) def test_case_13(): pytorch_code = textwrap.dedent( """ import torch + # paddle returns paddle.FloatTensor etc, so drop the namespace + # prefix and compare the remaining segments result = [ - torch.ones(1, dtype=torch.bool, device="cpu").type(), - torch.ones(1, dtype=torch.int32, device="cpu").type(), - torch.ones(1, dtype=torch.float64, device="cpu").type(), - torch.ones(1, dtype=torch.bfloat16, device="cpu").type(), - torch.ones(1, dtype=torch.complex64, device="cpu").type(), + t.type().split(".", 1)[1] + for t in ( + torch.ones(1, dtype=torch.bool, device="cpu"), + torch.ones(1, dtype=torch.int32, device="cpu"), + torch.ones(1, dtype=torch.float64, device="cpu"), + torch.ones(1, dtype=torch.bfloat16, device="cpu"), + torch.ones(1, dtype=torch.complex64, device="cpu"), + ) ] """ ) - obj.run( - pytorch_code, - ["result"], - check_value=False, - reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", - ) + obj.run(pytorch_code, ["result"]) def test_case_14(): @@ -231,15 +219,12 @@ def test_case_16(): """ import torch a = torch.ones(2, 3) + # paddle returns paddle.FloatTensor etc, so drop the namespace + # prefix and compare the remaining segments result = [ - a.type("torch.Float8_e4m3fnTensor").type(), - a.type("torch.Float8_e5m2Tensor").type(), + a.type("torch.Float8_e4m3fnTensor").type().split(".", 1)[1], + a.type("torch.Float8_e5m2Tensor").type().split(".", 1)[1], ] """ ) - obj.run( - pytorch_code, - ["result"], - check_value=False, - reason="Pytorch return tensor type name like 'torch.FloatTensor' while Paddle return dtype name like 'paddle.float32'", - ) + obj.run(pytorch_code, ["result"]) From d5d6198e6554535a60a2da75571f5ea377fdd84d Mon Sep 17 00:00:00 2001 From: wenfei qi Date: Sat, 15 Aug 2026 23:05:03 +0800 Subject: [PATCH 33/34] address review feedback: isolate state-polluting tests and align softmin config - reduce_scatter_tensor: use paddle.split instead of paddle.compat.split - tests/apibase.py: restore the original test mechanism and run the state-polluting tests separately via the CI isolated list - softmin: switch to the new enable_compat-based config - tests/test_Tensor_type.py: compare the converted tensor directly when a dtype is given, without stripping the type-name namespace prefix --- paconvert/api_mapping.json | 8 +-- paconvert/api_matcher.py | 39 +++-------- scripts/ci/run_cpu_unittest.sh | 3 + scripts/ci/run_gpu_unittest.sh | 2 + tests/apibase.py | 121 +++++++-------------------------- tests/test_Tensor_type.py | 10 +-- 6 files changed, 45 insertions(+), 138 deletions(-) diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 32199f0a8..6a688c674 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -6925,16 +6925,10 @@ }, "torch.nn.Softmin": { "Matcher": "SoftminMatcher", - "paddle_api": "paddle.nn.Softmax", + "paddle_api": "Softmin", "args_list": [ "dim" ], - "kwargs_change": { - "dim": "axis" - }, - "paddle_default_kwargs": { - "axis": null - }, "min_input_args": 0 }, "torch.nn.Softplus": { diff --git a/paconvert/api_matcher.py b/paconvert/api_matcher.py index 8bedabed2..9cef07efe 100644 --- a/paconvert/api_matcher.py +++ b/paconvert/api_matcher.py @@ -3012,26 +3012,12 @@ def generate_code(self, kwargs): class FSoftMinMatcher(BaseMatcher): - def generate_utils_code(self): - CODE_TEMPLATE = textwrap.dedent( - """ - def _get_softmin_dim(axis: int) -> int: - if axis == 0 or axis == 1 or axis == 3: - return 0 - else: - return 1 - """ - ) - return CODE_TEMPLATE - def generate_code(self, kwargs): + # torch.nn.functional.softmin(x, dim) equals softmax(-x, dim); under + # enable_compat(level=2) paddle.nn.functional.softmax already follows + # the torch signature, including the implicit dim choice for dim=None. kwargs["input"] = f"-{kwargs['input']}" - if "dim" not in kwargs or kwargs["dim"] == "None": - self.enable_utils_code() - kwargs["dim"] = "_get_softmin_dim({}.ndim)".format(kwargs["input"]) - return GenericMatcher.generate_code(self, kwargs) - else: - return GenericMatcher.generate_code(self, kwargs) + return GenericMatcher.generate_code(self, kwargs) class MSortMatcher(BaseMatcher): @@ -4084,18 +4070,13 @@ def generate_code(self, kwargs): def generate_utils_code(self): CODE_TEMPLATE = textwrap.dedent( """ - def _get_softmax_dim(axis: int) -> int: - if axis == 0 or axis == 1 or axis == 3: - ret = 0 - else: - ret = 1 - return ret + class Softmin(paddle.nn.Layer): + def __init__(self, dim=None): + super().__init__() + self.dim = dim - class Softmin(paddle.nn.Softmax): def forward(self, x): - if self._axis is None: - return paddle.nn.functional.softmax(-x, _get_softmax_dim(x.ndim)) - return paddle.nn.functional.softmax(-x, self._axis) + return paddle.nn.functional.softmax(-x, dim=self.dim) """ ) return CODE_TEMPLATE @@ -5799,7 +5780,7 @@ def reduce_scatter_tensor(output, input, op, group, async_op): if input.shape[0] == world_size: input_list = paddle.unstack(input, axis=0) else: - input_list = paddle.compat.split(input, world_size, dim=0) + input_list = paddle.split(input, world_size, dim=0) paddle.distributed.reduce_scatter(output, input_list, op, group, async_op) """ ) diff --git a/scripts/ci/run_cpu_unittest.sh b/scripts/ci/run_cpu_unittest.sh index 6d12cfa69..5efcc2d11 100644 --- a/scripts/ci/run_cpu_unittest.sh +++ b/scripts/ci/run_cpu_unittest.sh @@ -39,7 +39,10 @@ echo "Checking code cpu unit test by pytest ..." set +e ISOLATED_TESTS=( + tests/test_set_num_threads.py tests/test_set_num_interop_threads.py + tests/test_set_default_dtype.py + tests/test_set_default_tensor_type.py ) PYTEST_IGNORE=( diff --git a/scripts/ci/run_gpu_unittest.sh b/scripts/ci/run_gpu_unittest.sh index bab55b7e5..af94f6496 100644 --- a/scripts/ci/run_gpu_unittest.sh +++ b/scripts/ci/run_gpu_unittest.sh @@ -48,6 +48,8 @@ ISOLATED_TESTS=( tests/test_get_default_device.py tests/test_set_num_threads.py tests/test_set_num_interop_threads.py + tests/test_set_default_dtype.py + tests/test_set_default_tensor_type.py ) PYTEST_IGNORE=( diff --git a/tests/apibase.py b/tests/apibase.py index b744a356e..a882e18d9 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import contextlib import difflib import os import re @@ -24,62 +23,6 @@ from paconvert.converter import Converter -_SENTINEL = object() - - -def _snapshot_patches(paddle): - """Snapshot paddle classes that converted code patches via ``setattr``. - - The helper is defined in the exec namespace but the patch lands on the - global class, so it must be reverted after each test. - """ - targets = [paddle.Tensor] - nn = getattr(paddle, "nn", None) - if nn is not None: - for name in dir(nn): - obj = getattr(nn, name, None) - if isinstance(obj, type): - targets.append(obj) - - snap = [] - for target in targets: - snap.append((target, dict(vars(target)))) - return snap - - -def _is_compat_owned(obj): - """Whether ``obj`` is a ``paddle.enable_compat`` dispatcher rather than a test patch. - - Compat keeps its own list of what it replaced, so reverting these behind - paddle's back leaves it unable to reinstall them. - """ - return hasattr(obj, "__compat_fn__") or hasattr(obj, "__native_fn__") - - -def _restore_patches(snap): - """Revert only the attributes the exec'd code added or replaced.""" - for target, attrs in snap: - current = dict(vars(target)) - for name, original in attrs.items(): - now = current.get(name, _SENTINEL) - if now is original or _is_compat_owned(now): - continue - setattr(target, name, original) - for name, now in current.items(): - if name in attrs or _is_compat_owned(now): - continue - delattr(target, name) - - -@contextlib.contextmanager -def _compat_disabled(paddle): - """Run the block with compat off, and leave it off afterwards.""" - paddle.disable_compat() - try: - yield - finally: - paddle.disable_compat() - class APIBase(object): def __init__(self, pytorch_api) -> None: @@ -150,36 +93,29 @@ def run( pytorch_result = [pytorch_ns[name] for name in compared_tensor_names] pytorch_ns.clear() - import paddle - paddle_ns = {} - with _compat_disabled(paddle): - patch_snap = _snapshot_patches(paddle) - try: - exec(paddle_code, paddle_ns) - except Exception as e: - raise RuntimeError(f"Failed to execute paddle code:\n{e}") - paddle_result = [paddle_ns[name] for name in compared_tensor_names] + try: + exec(paddle_code, paddle_ns) + except Exception as e: + raise RuntimeError(f"Failed to execute paddle code:\n{e}") + paddle_result = [paddle_ns[name] for name in compared_tensor_names] + paddle_ns.clear() + for i in range(len(compared_tensor_names)): try: - for i in range(len(compared_tensor_names)): - try: - self.compare( - self.pytorch_api, - pytorch_result[i], - paddle_result[i], - check_value, - check_shape, - check_dtype, - check_stop_gradient, - rtol, - atol, - ) - except Exception as e: - raise AssertionError(f"Unable to align results: {e}") - finally: - _restore_patches(patch_snap) - paddle_ns.clear() + self.compare( + self.pytorch_api, + pytorch_result[i], + paddle_result[i], + check_value, + check_shape, + check_dtype, + check_stop_gradient, + rtol, + atol, + ) + except Exception as e: + raise AssertionError(f"Unable to align results: {e}") else: pytorch_ns = {} try: @@ -189,18 +125,13 @@ def run( finally: pytorch_ns.clear() - import paddle - paddle_ns = {} - with _compat_disabled(paddle): - patch_snap = _snapshot_patches(paddle) - try: - exec(paddle_code, paddle_ns) - except Exception as e: - raise RuntimeError(f"Failed to execute paddle code:\n{e}") - finally: - _restore_patches(patch_snap) - paddle_ns.clear() + try: + exec(paddle_code, paddle_ns) + except Exception as e: + raise RuntimeError(f"Failed to execute paddle code:\n{e}") + finally: + paddle_ns.clear() def compare( self, diff --git a/tests/test_Tensor_type.py b/tests/test_Tensor_type.py index 48e439bae..ad06de453 100644 --- a/tests/test_Tensor_type.py +++ b/tests/test_Tensor_type.py @@ -92,9 +92,7 @@ def test_case_7(): """ import torch a = torch.ones(2, 3, device="cpu") - # paddle returns paddle.FloatTensor etc, so drop the namespace - # prefix and compare the remaining segments - result = a.type(dtype=None, non_blocking=False).split(".", 1)[1] + result = a.type(dtype=torch.float64, non_blocking=False) """ ) obj.run(pytorch_code, ["result"]) @@ -140,10 +138,8 @@ def test_case_11(): """ import torch a = torch.ones(2, 3, device="cpu") - kwargs = {"async": True} - # paddle returns paddle.FloatTensor etc, so drop the namespace - # prefix and compare the remaining segments - result = a.type(**kwargs).split(".", 1)[1] + kwargs = {"dtype": torch.float64, "async": True} + result = a.type(**kwargs) """ ) obj.run(pytorch_code, ["result"]) From 6faa192b6e95a53e66b68c8d15ed8cf08c042cb6 Mon Sep 17 00:00:00 2001 From: manfredss Date: Mon, 17 Aug 2026 02:09:19 +0000 Subject: [PATCH 34/34] delete comments --- tests/test_Tensor_type.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/test_Tensor_type.py b/tests/test_Tensor_type.py index ad06de453..61e3e8069 100644 --- a/tests/test_Tensor_type.py +++ b/tests/test_Tensor_type.py @@ -57,8 +57,6 @@ def test_case_4(): """ import torch a = torch.Tensor([1,2,3]) - # paddle returns paddle.FloatTensor etc, so drop the namespace - # prefix and compare the remaining segments result = a.type().split(".", 1)[1] """ ) @@ -154,8 +152,6 @@ def test_case_12(): a = torch.sparse_coo_tensor( indices, values, [2, 2], device="cpu" ) - # paddle returns paddle.FloatTensor etc, so drop the namespace - # prefix and compare the remaining segments result = a.type().split(".", 1)[1] """ ) @@ -166,8 +162,6 @@ def test_case_13(): pytorch_code = textwrap.dedent( """ import torch - # paddle returns paddle.FloatTensor etc, so drop the namespace - # prefix and compare the remaining segments result = [ t.type().split(".", 1)[1] for t in ( @@ -215,8 +209,6 @@ def test_case_16(): """ import torch a = torch.ones(2, 3) - # paddle returns paddle.FloatTensor etc, so drop the namespace - # prefix and compare the remaining segments result = [ a.type("torch.Float8_e4m3fnTensor").type().split(".", 1)[1], a.type("torch.Float8_e5m2Tensor").type().split(".", 1)[1],