diff --git a/README.md b/README.md index 04950f5eb..60a437e98 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,6 @@ ## 安装使用 -#### 1. 命令行用法 - 通过终端命令行的方式使用: ```bash @@ -44,15 +42,6 @@ paconvert -i torch_code_dir [-o paddle_code_dir] [-e exclude.py] [--log_dir log_ --exclude_packages 可选,可以配置无需识别转换的torch包名,多个包名请使用逗号分隔。默认不配置。 ``` -#### 2. IDE交互式用法 - -在 IDE 中使用,交互式界面更友好。 - -需要在`PyCharm`或`VS Code`等主流 IDE 中安装 **文心快码插件(Baidu Comate)** 后即可使用。以`VS Code`上使用为例: - -![img](./images/comate_paconvert.jpeg) - - ## 转换示例 以下面一个简单的 Pytorch Demo 代码为例: diff --git a/paconvert/api_mapping.json b/paconvert/api_mapping.json index 9769aaa5c..93337456f 100644 --- a/paconvert/api_mapping.json +++ b/paconvert/api_mapping.json @@ -818,40 +818,13 @@ "paddle_api": "paddle.Tensor.crows" }, "torch.Tensor.cuda": { - "Matcher": "Device2IntMatcher", - "paddle_api": "paddle.Tensor.cuda", - "min_input_args": 0, - "args_list": [ - "device", - "non_blocking", - "memory_format" - ], - "kwargs_change": { - "device": "device_id", - "memory_format": "" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.cummax": { - "Matcher": "DoubleAssignMatcher", - "paddle_api": "paddle.Tensor.cummax", - "min_input_args": 1, - "args_list": [ - "dim" - ], - "kwargs_change": { - "dim": "axis" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.cummin": { - "Matcher": "DoubleAssignMatcher", - "paddle_api": "paddle.Tensor.cummin", - "min_input_args": 1, - "args_list": [ - "dim" - ], - "kwargs_change": { - "dim": "axis" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.cumprod": { "Matcher": "ChangePrefixMatcher" @@ -899,20 +872,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.diagonal_scatter": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.Tensor.diagonal_scatter", - "min_input_args": 1, - "args_list": [ - "src", - "offset", - "dim1", - "dim2" - ], - "kwargs_change": { - "src": "y", - "dim1": "axis1", - "dim2": "axis2" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.diff": { "Matcher": "ChangePrefixMatcher" @@ -1003,9 +963,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.erf_": { - "Matcher": "TensorFunc2PaddleFunc", - "paddle_api": "paddle.erf_", - "min_input_args": 0 + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.erfc": { "Matcher": "ErfCMatcher", @@ -1395,15 +1353,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.inner": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.Tensor.inner", - "min_input_args": 1, - "args_list": [ - "other" - ], - "kwargs_change": { - "other": "y" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.int": { "Matcher": "ChangePrefixMatcher" @@ -1482,15 +1432,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.ldexp": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.Tensor.ldexp", - "min_input_args": 1, - "args_list": [ - "other" - ], - "kwargs_change": { - "other": "y" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.ldexp_": { "Matcher": "ChangePrefixMatcher" @@ -1837,19 +1779,7 @@ ] }, "torch.Tensor.nanquantile": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.Tensor.nanquantile", - "min_input_args": 1, - "args_list": [ - "q", - "dim", - "keepdim", - "*", - "interpolation" - ], - "kwargs_change": { - "dim": "axis" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.nansum": { "Matcher": "GenericMatcher", @@ -2027,8 +1957,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.positive": { - "Matcher": "TensorFunc2PaddleFunc", - "paddle_api": "paddle.positive" + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.pow": { "Matcher": "ChangePrefixMatcher" @@ -2153,16 +2082,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.rot90": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.Tensor.rot90", - "min_input_args": 0, - "args_list": [ - "k", - "dims" - ], - "kwargs_change": { - "dims": "axes" - } + "Matcher": "ChangePrefixMatcher" }, "torch.Tensor.round": { "Matcher": "ChangePrefixMatcher" @@ -3388,9 +3308,6 @@ "torch.autograd.function.FunctionCtx.save_for_forward": { "min_input_args": 0 }, - "torch.autograd.function.FunctionCtx.saved_tensors": { - "Matcher": "ChangePrefixMatcher" - }, "torch.autograd.function.FunctionCtx.set_materialize_grads": { "Matcher": "ChangePrefixMatcher" }, @@ -4071,34 +3988,10 @@ "Matcher": "ChangePrefixMatcher" }, "torch.cummax": { - "Matcher": "DoubleAssignMatcher", - "paddle_api": "paddle.cummax", - "min_input_args": 2, - "args_list": [ - "input", - "dim", - "*", - "out" - ], - "kwargs_change": { - "input": "x", - "dim": "axis" - } + "Matcher": "ChangePrefixMatcher" }, "torch.cummin": { - "Matcher": "DoubleAssignMatcher", - "paddle_api": "paddle.cummin", - "min_input_args": 2, - "args_list": [ - "input", - "dim", - "*", - "out" - ], - "kwargs_change": { - "input": "x", - "dim": "axis" - } + "Matcher": "ChangePrefixMatcher" }, "torch.cumprod": { "Matcher": "ChangePrefixMatcher" @@ -4140,37 +4033,13 @@ "Matcher": "ChangePrefixMatcher" }, "torch.diagflat": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.diagflat", - "min_input_args": 1, - "args_list": [ - "input", - "offset" - ], - "kwargs_change": { - "input": "x" - } + "Matcher": "ChangePrefixMatcher" }, "torch.diagonal": { "Matcher": "ChangePrefixMatcher" }, "torch.diagonal_scatter": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.diagonal_scatter", - "min_input_args": 2, - "args_list": [ - "input", - "src", - "offset", - "dim1", - "dim2" - ], - "kwargs_change": { - "input": "x", - "src": "y", - "dim1": "axis1", - "dim2": "axis2" - } + "Matcher": "ChangePrefixMatcher" }, "torch.diff": { "Matcher": "ChangePrefixMatcher" @@ -5333,6 +5202,9 @@ "Matcher": "ChangeAPIMatcher", "paddle_api": "paddle.compat.equal" }, + "torch.erf": { + "Matcher": "ChangePrefixMatcher" + }, "torch.exp": { "Matcher": "ChangePrefixMatcher" }, @@ -5456,9 +5328,6 @@ "axis": 0 } }, - "torch.float8_e4m3fn": { - "Matcher": "ChangePrefixMatcher" - }, "torch.float_power": { "Matcher": "FloatPowerMatcher", "min_input_args": 2, @@ -5809,15 +5678,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.iinfo": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.iinfo", - "min_input_args": 1, - "args_list": [ - "type" - ], - "kwargs_change": { - "type": "dtype" - } + "Matcher": "ChangePrefixMatcher" }, "torch.imag": { "Matcher": "GenericMatcher", @@ -5866,19 +5727,7 @@ "min_input_args": 0 }, "torch.inner": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.inner", - "min_input_args": 2, - "args_list": [ - "input", - "other", - "*", - "out" - ], - "kwargs_change": { - "input": "x", - "other": "y" - } + "Matcher": "ChangePrefixMatcher" }, "torch.instance_norm": {}, "torch.inverse": { @@ -6049,19 +5898,7 @@ } }, "torch.ldexp": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.ldexp", - "min_input_args": 2, - "args_list": [ - "input", - "other", - "*", - "out" - ], - "kwargs_change": { - "input": "x", - "other": "y" - } + "Matcher": "ChangePrefixMatcher" }, "torch.le": { "Matcher": "ChangePrefixMatcher" @@ -6906,22 +6743,7 @@ "paddle_api": "paddle.compat.nanmedian" }, "torch.nanquantile": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.nanquantile", - "min_input_args": 2, - "args_list": [ - "input", - "q", - "dim", - "keepdim", - "*", - "interpolation", - "out" - ], - "kwargs_change": { - "input": "x", - "dim": "axis" - } + "Matcher": "ChangePrefixMatcher" }, "torch.nansum": { "Matcher": "GenericMatcher", @@ -6960,17 +6782,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.neg": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.neg", - "min_input_args": 1, - "args_list": [ - "input", - "*", - "out" - ], - "kwargs_change": { - "input": "x" - } + "Matcher": "ChangePrefixMatcher" }, "torch.negative": { "Matcher": "GenericMatcher", @@ -10560,15 +10372,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.positive": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.positive", - "min_input_args": 1, - "args_list": [ - "input" - ], - "kwargs_change": { - "input": "x" - } + "Matcher": "ChangePrefixMatcher" }, "torch.pow": { "Matcher": "ChangePrefixMatcher" @@ -10615,17 +10419,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.rad2deg": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.rad2deg", - "min_input_args": 1, - "args_list": [ - "input", - "*", - "out" - ], - "kwargs_change": { - "input": "x" - } + "Matcher": "ChangePrefixMatcher" }, "torch.rand": { "Matcher": "ChangePrefixMatcher" @@ -10735,18 +10529,7 @@ "Matcher": "ChangePrefixMatcher" }, "torch.rot90": { - "Matcher": "GenericMatcher", - "paddle_api": "paddle.rot90", - "min_input_args": 1, - "args_list": [ - "input", - "k", - "dims" - ], - "kwargs_change": { - "input": "x", - "dims": "axes" - } + "Matcher": "ChangePrefixMatcher" }, "torch.round": { "Matcher": "ChangePrefixMatcher" diff --git a/paconvert/attribute_mapping.json b/paconvert/attribute_mapping.json index c4ab3d146..57dbbf1ae 100644 --- a/paconvert/attribute_mapping.json +++ b/paconvert/attribute_mapping.json @@ -68,7 +68,7 @@ }, "torch.autograd.function.FunctionCtx.saved_tensors": { "Matcher": "Attribute2Func", - "paddle_api": "paddle.autograd.PyLayerContext.saved_tensor" + "paddle_api": "paddle.autograd.function.FunctionCtx.saved_tensor" }, "torch.autograd.profiler.profile.self_cpu_time_total": {}, "torch.backends.cuda.matmul.allow_tf32": { @@ -148,6 +148,9 @@ "torch.float64": { "Matcher": "ChangePrefixMatcher" }, + "torch.float8_e4m3fn": { + "Matcher": "ChangePrefixMatcher" + }, "torch.inf": { "Matcher": "ChangePrefixMatcher" }, diff --git a/paconvert/base.py b/paconvert/base.py index 67cb76049..47ff47061 100644 --- a/paconvert/base.py +++ b/paconvert/base.py @@ -383,7 +383,7 @@ def parse_func(self, func): self.paddleClass = new_func[0 : new_func.rfind(".")] if self.get_paddle_api(): new_paddle_api = re.sub( - "paddle.Tensor|paddle.nn.Module|paddle.optimizer.Optimizer|paddle.distribution.Distribution|paddle.autograd.function.FunctionCtx|paddle.autograd.PyLayerContext|paddle.profiler.Profiler", + "paddle.Tensor|paddle.nn.Module|paddle.optimizer.Optimizer|paddle.distribution.Distribution|paddle.autograd.function.FunctionCtx|paddle.profiler.Profiler", re.escape(self.paddleClass), self.get_paddle_api(), ) diff --git a/paconvert/converter.py b/paconvert/converter.py index 88cde169f..e0720eae1 100644 --- a/paconvert/converter.py +++ b/paconvert/converter.py @@ -27,9 +27,6 @@ from paconvert.transformer.basic_transformer import BasicTransformer from paconvert.transformer.import_transformer import ImportTransformer -from paconvert.transformer.tensor_requires_grad_transformer import ( - TensorRequiresGradTransformer, -) from paconvert.transformer.custom_op_transformer import ( PreCustomOpTransformer, CustomOpTransformer, @@ -260,6 +257,21 @@ def run(self, in_dir, out_dir=None, exclude=None): return self.success_api_count, faild_api_count + def __del__(self): + """Ensure cleanup happens when Converter is destroyed.""" + try: + # Close all logger handlers + for handler in self.logger.handlers[:]: + handler.close() + self.logger.removeHandler(handler) + + # Clear large data structures + self.imports_map.clear() + self.all_api_map.clear() + self.unsupport_api_map.clear() + except: + pass + def transfer_dir(self, in_dir, out_dir, exclude): if os.path.isfile(in_dir): old_path = in_dir @@ -378,7 +390,6 @@ def transfer_file(self, old_path, new_path): def transfer_node(self, root, file): transformers = [ ImportTransformer, # import ast transformer - TensorRequiresGradTransformer, # attribute requires_grad transformer BasicTransformer, # most of api transformer PreCustomOpTransformer, # pre process for C++ custom op CustomOpTransformer, # C++ custom op transformer diff --git a/paconvert/transformer/basic_transformer.py b/paconvert/transformer/basic_transformer.py index 5e1a9d6a1..60dded086 100644 --- a/paconvert/transformer/basic_transformer.py +++ b/paconvert/transformer/basic_transformer.py @@ -119,10 +119,14 @@ def visit_Attribute(self, node): node.lineno, ) - matcher = self.get_api_matcher(torch_api) - # can be api_matcher or attribute_matcher - if matcher is None: - matcher = self.get_attribute_mather(torch_api) + # can in attribute_matcher or attribute_matcher, but not both + attribute_matcher = self.get_attribute_matcher(torch_api) + api_matcher = self.get_api_matcher(torch_api) + assert not ( + attribute_matcher and api_matcher + ), f"{torch_api} can not be both in attribute_matcher and api_matcher" + + matcher = attribute_matcher or api_matcher if matcher: paddle_api = matcher.get_paddle_api() @@ -275,7 +279,7 @@ def visit_Attribute(self, node): return node def trans_class_attribute(self, node, torch_api): - matcher = self.get_attribute_mather(torch_api) + matcher = self.get_attribute_matcher(torch_api) if matcher: self.all_api_map[torch_api]["paddle_api"] = ( matcher.get_paddle_api() if matcher.get_paddle_api() else "" @@ -736,6 +740,9 @@ def in_api_mapping(self, torch_api): def get_api_matcher(self, torch_api): api_mapping_dict = {} if torch_api in GlobalManager.ALIAS_MAPPING: + assert ( + torch_api not in GlobalManager.API_MAPPING + ), f"{torch_api} can not be both in alias mapping and api mapping" torch_api = GlobalManager.ALIAS_MAPPING[torch_api] if torch_api in GlobalManager.API_MAPPING: api_mapping_dict = GlobalManager.API_MAPPING[torch_api] @@ -759,10 +766,12 @@ def in_attribute_mapping(self, torch_api): return True return False - def get_attribute_mather(self, torch_api): + def get_attribute_matcher(self, torch_api): attr_mapping_dict = {} - if torch_api in GlobalManager.ALIAS_MAPPING: + assert ( + torch_api not in GlobalManager.ATTRIBUTE_MAPPING + ), f"{torch_api} can not be both in alias mapping and attribute mapping" torch_api = GlobalManager.ALIAS_MAPPING[torch_api] if torch_api in GlobalManager.ATTRIBUTE_MAPPING: attr_mapping_dict = GlobalManager.ATTRIBUTE_MAPPING[torch_api] diff --git a/tests/pytest.ini b/pytest.ini similarity index 84% rename from tests/pytest.ini rename to pytest.ini index 406bf8906..5a8b7e3ba 100644 --- a/tests/pytest.ini +++ b/pytest.ini @@ -1,4 +1,4 @@ [pytest] ; print user output; clear warning addopts = -v -s -p no:warnings -timeout = 300 +timeout = 100 diff --git a/scripts/unittest_check.sh b/scripts/unittest_check.sh index 14d9ff559..1d4065ae1 100644 --- a/scripts/unittest_check.sh +++ b/scripts/unittest_check.sh @@ -47,7 +47,7 @@ python -m pip install -r requirements.txt echo '************************************************************************************************************' echo "Checking code unit test by pytest ..." python -m pip install pytest-timeout -python -m pytest ./tests;check_error=$? +python -m pytest -v -s -p no:warnings ./tests;check_error=$? echo '************************************************************************************************************' echo "______ _____ _ " diff --git a/scripts/unittest_check_gpu.sh b/scripts/unittest_check_gpu.sh index ada1a49e4..97effc388 100644 --- a/scripts/unittest_check_gpu.sh +++ b/scripts/unittest_check_gpu.sh @@ -47,10 +47,10 @@ python -m pip install -r requirements.txt echo '************************************************************************************************************' echo "Checking code unit test by pytest ..." python -m pip install pytest-timeout pytest-xdist pytest-rerunfailures -python -m pytest -n 1 --reruns=3 ./tests; check_error=$? +python -m pytest -v -s -p no:warnings -n 1 --reruns=3 ./tests; check_error=$? if [ ${check_error} != 0 ];then echo "Rerun unit test check." - python -m pytest -n 1 --lf ./tests; check_error=$? + python -m pytest -v -s -p no:warnings -n 1 --lf ./tests; check_error=$? fi echo '************************************************************************************************************' diff --git a/tests/apibase.py b/tests/apibase.py index 2e67c9670..a882e18d9 100644 --- a/tests/apibase.py +++ b/tests/apibase.py @@ -85,17 +85,22 @@ def run( ) assert paddle_code == expect_paddle_code, error_msg elif compared_tensor_names: - loc = locals() + pytorch_ns = {} try: - exec(pytorch_code, locals()) + exec(pytorch_code, pytorch_ns) except Exception as e: raise RuntimeError(f"Failed to execute pytorch code:\n{e}") - pytorch_result = [loc[name] for name in compared_tensor_names] + pytorch_result = [pytorch_ns[name] for name in compared_tensor_names] + pytorch_ns.clear() + + paddle_ns = {} try: - exec(paddle_code, locals()) + exec(paddle_code, paddle_ns) except Exception as e: raise RuntimeError(f"Failed to execute paddle code:\n{e}") - paddle_result = [loc[name] for name in compared_tensor_names] + 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( @@ -112,14 +117,21 @@ def run( except Exception as e: raise AssertionError(f"Unable to align results: {e}") else: + pytorch_ns = {} try: - exec(pytorch_code, locals()) + exec(pytorch_code, pytorch_ns) except Exception as e: raise RuntimeError(f"Failed to execute pytorch code:\n{e}") + finally: + pytorch_ns.clear() + + paddle_ns = {} try: - exec(paddle_code, locals()) + 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/code_library/code_case/paddle_code/attribute_paddle_Tensor_stop_gradient.py b/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py similarity index 90% rename from tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_stop_gradient.py rename to tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py index a18301a08..10351335a 100644 --- a/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_stop_gradient.py +++ b/tests/code_library/code_case/paddle_code/attribute_paddle_Tensor_requires_grad.py @@ -7,7 +7,7 @@ print("#########################case2#########################") print(data.requires_grad) print("#########################case3#########################") -data.stop_gradient = not False +data.requires_grad = False print("#########################case4#########################") requires_grad = data.requires_grad print("#########################case5#########################") @@ -25,9 +25,8 @@ def test(): return True -data.stop_gradient = not test() +data.requires_grad = test() print("#########################case10#########################") z = True, False, True -a, temp, c = z -data.stop_gradient = not temp +a, data.requires_grad, c = z print(data.requires_grad) diff --git a/tests/test_Tensor_cummax.py b/tests/test_Tensor_cummax.py index 07c05c91e..dc94f4901 100644 --- a/tests/test_Tensor_cummax.py +++ b/tests/test_Tensor_cummax.py @@ -20,52 +20,88 @@ def test_case_1(): + """Test basic usage with positional and keyword arguments""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) + x = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) result = x.cummax(0) + result2 = x.cummax(dim=1) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result", "result2"]) def test_case_2(): + """Test with 1D and 3D tensors""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = x.cummax(1) + x1d = torch.tensor([3.0, 1.0, 4.0, 1.0, 5.0]) + result1 = x1d.cummax(0) + + x3d = torch.tensor([[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]]) + result2 = x3d.cummax(dim=1) + result3 = x3d.cummax(dim=2) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result1", "result2", "result3"]) def test_case_3(): + """Test with different dtypes and values""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = x.cummax(dim=1) + x_float64 = torch.tensor([[1.0, 2.0]], dtype=torch.float64) + result1 = x_float64.cummax(0) + + x_neg = torch.tensor([[-1.0, 2.0], [-3.0, 4.0]]) + result2 = x_neg.cummax(dim=1) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result1", "result2"]) def test_case_4(): + """Test NamedTuple access (values, indices and [0], [1])""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) + result = x.cummax(0) + values = result.values + indices = result.indices + v0 = result[0] + i1 = result[1] + """ + ) + obj.run(pytorch_code, ["values", "indices", "v0", "i1"]) + + +def test_case_5(): + """Test NamedTuple access with 3D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]]) + result = x.cummax(dim=1) + values = result.values + indices = result.indices + """ + ) + obj.run(pytorch_code, ["values", "indices"]) + + +def test_case_6(): + """Test NamedTuple access with negative values""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = x.cummax(dim=0) + x = torch.tensor([[-1.0, 2.0], [-3.0, 4.0]]) + result = x.cummax(dim=1) + values = result.values + indices = result.indices """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["values", "indices"]) diff --git a/tests/test_Tensor_cummin.py b/tests/test_Tensor_cummin.py index 4acc5d5fb..12463d92a 100644 --- a/tests/test_Tensor_cummin.py +++ b/tests/test_Tensor_cummin.py @@ -20,52 +20,88 @@ def test_case_1(): + """Test basic usage with positional and keyword arguments""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) + x = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) result = x.cummin(0) + result2 = x.cummin(dim=1) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result", "result2"]) def test_case_2(): + """Test with 1D and 3D tensors""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = x.cummin(1) + x1d = torch.tensor([9.0, 5.0, 2.0, 7.0]) + result1 = x1d.cummin(0) + + x3d = torch.tensor([[[12.0, 11.0], [10.0, 9.0]], [[8.0, 7.0], [6.0, 5.0]]]) + result2 = x3d.cummin(dim=1) + result3 = x3d.cummin(dim=2) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result1", "result2", "result3"]) def test_case_3(): + """Test with different dtypes and values""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = x.cummin(dim=1) + x_float64 = torch.tensor([[6.0, 5.0]], dtype=torch.float64) + result1 = x_float64.cummin(0) + + x_neg = torch.tensor([[-1.0, 2.0], [-3.0, 4.0]]) + result2 = x_neg.cummin(dim=1) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result1", "result2"]) def test_case_4(): + """Test NamedTuple access (values, indices and [0], [1])""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[4.0, 2.0], [1.0, 3.0]]) + result = x.cummin(0) + values = result.values + indices = result.indices + v0 = result[0] + i1 = result[1] + """ + ) + obj.run(pytorch_code, ["values", "indices", "v0", "i1"]) + + +def test_case_5(): + """Test NamedTuple access with 3D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[[12.0, 11.0], [10.0, 9.0]], [[8.0, 7.0], [6.0, 5.0]]]) + result = x.cummin(dim=1) + values = result.values + indices = result.indices + """ + ) + obj.run(pytorch_code, ["values", "indices"]) + + +def test_case_6(): + """Test NamedTuple access with negative values""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = x.cummin(dim=0) + x = torch.tensor([[-1.0, 2.0], [-3.0, 4.0]]) + result = x.cummin(dim=1) + values = result.values + indices = result.indices """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["values", "indices"]) diff --git a/tests/test_Tensor_diagflat.py b/tests/test_Tensor_diagflat.py index ad2f5ab64..bea7d6300 100644 --- a/tests/test_Tensor_diagflat.py +++ b/tests/test_Tensor_diagflat.py @@ -50,3 +50,87 @@ def test_case_3(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_4(): + """Test with negative offset""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1, 2, 3]) + result = a.diagflat(offset=-1) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_5(): + """Test with float64 dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float64) + result = a.diagflat() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + """Test with 2D input tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[1, 2], [3, 4]]) + result = a.diagflat() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + """Test with 2D tensor and positive offset""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32) + result = a.diagflat(offset=2) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + """Test with int dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1.0, 2.0, 3.0]) + result = a.diagflat(-2) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + """Test with single element tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([5.0]) + result = a.diagflat() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + """Test with int dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1, 2, 3, 4], dtype=torch.int64) + result = a.diagflat(offset=1) + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_Tensor_diagonal_scatter.py b/tests/test_Tensor_diagonal_scatter.py index 77d6854a3..4c0c2e9a0 100644 --- a/tests/test_Tensor_diagonal_scatter.py +++ b/tests/test_Tensor_diagonal_scatter.py @@ -77,3 +77,68 @@ def test_case_5(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + """Test with positive offset""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(12.0).reshape((3, 4)) + src = torch.ones((3,)) + result = input.diagonal_scatter(src, offset=1) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + """Test with negative offset""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(12.0).reshape((3, 4)) + src = torch.ones((2,)) + result = input.diagonal_scatter(src, offset=-1) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + """Test with int dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(6, dtype=torch.int32).reshape((2, 3)) + src = torch.ones((2,), dtype=torch.int32) + result = input.diagonal_scatter(src) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + """Test with float64 dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(6.0, dtype=torch.float64).reshape((2, 3)) + src = torch.ones((2,), dtype=torch.float64) + result = input.diagonal_scatter(src, offset=0, dim1=0, dim2=1) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + """Test with 3D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(24.0).reshape((2, 3, 4)) + src = torch.ones((3, 2)) + result = input.diagonal_scatter(src, dim1=0, dim2=2) + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_Tensor_erf.py b/tests/test_Tensor_erf.py index 2ecfeb7ac..7c1c07de9 100644 --- a/tests/test_Tensor_erf.py +++ b/tests/test_Tensor_erf.py @@ -39,3 +39,65 @@ def test_case_2(): """ ) obj.run(pytorch_code, ["result"]) + + +# generated by validate_unittest autofix, based on test_case_3 +def test_case_3(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([0.5, -0.5, 1.5], dtype=torch.float32) + result = a.erf() + """ + ) + obj.run(pytorch_code, ["result"]) + + +# generated by validate_unittest autofix, based on test_case_5 +def test_case_4(): + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[0.1, 0.2], [-0.3, 0.4]]) + result = a.erf() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_5(): + """Test with different dimensions""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[[0.1, 0.2], [0.3, 0.4]], [[0.5, 0.6], [0.7, 0.8]]]) + result = a.erf() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + """Test with float64""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([0.5, 1.0, -0.5], dtype=torch.float64) + result = a.erf() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + """Test gradient computation""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([0.5, 1.0, -0.5], requires_grad=True) + y = a.erf() + y.sum().backward() + a_grad = a.grad + """ + ) + obj.run(pytorch_code, ["y", "a_grad"], check_stop_gradient=False) diff --git a/tests/test_Tensor_erf_.py b/tests/test_Tensor_erf_.py index a67d295b4..56d003a1d 100644 --- a/tests/test_Tensor_erf_.py +++ b/tests/test_Tensor_erf_.py @@ -29,3 +29,63 @@ def test_case_1(): """ ) obj.run(pytorch_code, ["a"]) + + +def test_case_2(): + """Test with float32""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([0.5, -0.5, 1.5], dtype=torch.float32) + result = a.erf_() + """ + ) + obj.run(pytorch_code, ["a", "result"]) + + +def test_case_3(): + """Test with 2D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[0.1, 0.2], [-0.3, 0.4]]) + result = a.erf_() + """ + ) + obj.run(pytorch_code, ["a", "result"]) + + +def test_case_4(): + """Test with 3D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[[0.1, 0.2], [0.3, 0.4]], [[0.5, 0.6], [0.7, 0.8]]]) + result = a.erf_() + """ + ) + obj.run(pytorch_code, ["a", "result"]) + + +def test_case_5(): + """Test with float64""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([0.5, 1.0, -0.5], dtype=torch.float64) + result = a.erf_() + """ + ) + obj.run(pytorch_code, ["a", "result"]) + + +def test_case_6(): + """Test return value equals original tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([0.5, 1.0, -0.5]) + b = a.erf_() + """ + ) + obj.run(pytorch_code, ["a", "b"]) diff --git a/tests/test_Tensor_ldexp.py b/tests/test_Tensor_ldexp.py index ee08afe89..5c33838f6 100644 --- a/tests/test_Tensor_ldexp.py +++ b/tests/test_Tensor_ldexp.py @@ -11,6 +11,7 @@ # 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 textwrap from apibase import APIBase @@ -59,3 +60,80 @@ def test_case_4(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_5(): + """Test with int second argument""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1., 2., 3.]) + b = torch.tensor([1, 2, 3]) + result = a.ldexp(b) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + """Test with float64 dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1.0, 2.0], dtype=torch.float64) + b = torch.tensor([1, 2], dtype=torch.int64) + result = a.ldexp(b) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + """Test with negative exponent""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1., 2., 4.]) + b = torch.tensor([-1, -2, -3]) + result = a.ldexp(b) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + """Test with zero exponent""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1., 2., 3.]) + b = torch.tensor([0, 0, 0]) + result = a.ldexp(b) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + """Test with 2D tensors""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[1., 2.], [3., 4.]]) + b = torch.tensor([[1, 2], [3, 4]]) + result = a.ldexp(b) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + """Test with keyword argument""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1., 2., 3.]) + result = a.ldexp(other=torch.tensor([1, 2, 3])) + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_Tensor_mode.py b/tests/test_Tensor_mode.py index 212b6c635..8f599421a 100644 --- a/tests/test_Tensor_mode.py +++ b/tests/test_Tensor_mode.py @@ -98,3 +98,31 @@ def test_case_7(): """ ) obj.run(pytorch_code, ["result", "index"]) + + +def test_case_8(): + """Test NamedTuple access (values, indices)""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.tensor([[[1,2,2],[2,3,3]],[[0,5,5],[9,9,0]]]) + result = input.mode(1) + values = result.values + indices = result.indices + """ + ) + obj.run(pytorch_code, ["values", "indices"]) + + +def test_case_9(): + """Test NamedTuple access with keepdim""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.tensor([[[1,2,2],[2,3,3]],[[0,5,5],[9,9,0]]]) + result = input.mode(dim=1, keepdim=True) + values = result.values + indices = result.indices + """ + ) + obj.run(pytorch_code, ["values", "indices"]) diff --git a/tests/test_Tensor_nanquantile.py b/tests/test_Tensor_nanquantile.py index ba7e7a389..f6fec2b4a 100644 --- a/tests/test_Tensor_nanquantile.py +++ b/tests/test_Tensor_nanquantile.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. - import textwrap from apibase import APIBase @@ -21,151 +20,240 @@ def test_case_1(): + """Basic usage with positional arguments""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([1.02, 2.21, 3.333, 30], dtype=torch.float64) + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) result = x.nanquantile(0.5) - """ + """ ) obj.run(pytorch_code, ["result"]) def test_case_2(): + """With dim parameter as positional argument""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([float('nan'), 2.21, 3.333, 30], dtype=torch.float64) - result = x.nanquantile(0.6, dim=0) - """ + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, 1) + """ ) obj.run(pytorch_code, ["result"]) def test_case_3(): + """With dim and keepdim parameters as positional arguments""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([float('nan'), 1.02, 2.21, 3.333,30, float('nan')], dtype=torch.float64) - result = x.nanquantile(q=0.3, dim=-1) - """ + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, 0, True) + """ ) obj.run(pytorch_code, ["result"]) def test_case_4(): + """With keepdim keyword argument""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[float('nan'), 1.02, 2.21, 3.333,30, float('nan')]], dtype=torch.float64) - result = x.nanquantile(q=0.3, dim=1, keepdim=True) - """ + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.25, 0, keepdim=True) + """ ) obj.run(pytorch_code, ["result"]) def test_case_5(): + """Multiple quantile values""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[float('nan'), 1.02, 2.21, 3.333,30, float('nan')]], dtype=torch.float64) - result = x.nanquantile(q=0.3, dim=1, keepdim=False) - """ + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(torch.tensor([0.25, 0.5, 0.75])) + """ ) obj.run(pytorch_code, ["result"]) def test_case_6(): + """3D tensor input""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[0]], dtype=torch.float64) - result = x.nanquantile(0.3, 1, True) - """ + x = torch.tensor([[[1.0, float('nan')], [3.0, 4.0]], [[5.0, 6.0], [float('nan'), 8.0]]]) + result = x.nanquantile(0.5, 2) + """ ) obj.run(pytorch_code, ["result"]) def test_case_7(): + """Mixed parameter styles with dim and keepdim""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[0]], dtype=torch.float64) - result = x.nanquantile(q=0.3, dim=1, keepdim=True, interpolation='higher') - """ - ) - obj.run( - pytorch_code, - ["result"], + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, dim=1, keepdim=True) + """ ) + obj.run(pytorch_code, ["result"]) -# generated by validate_unittest autofix, based on test_case_7 def test_case_8(): + """Verify NaN handling - all NaN row""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[0]], dtype=torch.float64) - result = x.nanquantile(interpolation='higher', keepdim=True, dim=1, q=0.3) - """ - ) - obj.run( - pytorch_code, - ["result"], + x = torch.tensor([[float('nan'), float('nan'), float('nan')], [1.0, 2.0, 3.0]]) + result = x.nanquantile(0.5, 1) + """ ) + obj.run(pytorch_code, ["result"]) def test_case_9(): + """Quantile at lower boundary""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[0]], dtype=torch.float64) - result = x.nanquantile(q=0.3, dim=1, keepdim=True, interpolation='lower') + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.0, 1) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + """Quantile at upper boundary""" + pytorch_code = textwrap.dedent( """ + import torch + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(1.0, 1) + """ ) - obj.run( - pytorch_code, - ["result"], + obj.run(pytorch_code, ["result"]) + + +def test_case_11(): + """Chained method calls""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, 1).nanquantile(0.5) + """ ) + obj.run(pytorch_code, ["result"]) -def test_case_10(): +def test_case_12(): + """With interpolation='lower'""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[0]], dtype=torch.float64) - result = x.nanquantile(q=0.3, dim=1, keepdim=True, interpolation='nearest') + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, dim=1, interpolation='lower') + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_13(): + """With interpolation='higher'""" + pytorch_code = textwrap.dedent( """ + import torch + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, dim=1, interpolation='higher') + """ ) - obj.run( - pytorch_code, - ["result"], + obj.run(pytorch_code, ["result"]) + + +def test_case_14(): + """With interpolation='midpoint'""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, dim=1, interpolation='midpoint') + """ ) + obj.run(pytorch_code, ["result"]) -def test_case_11(): +def test_case_15(): + """With interpolation='nearest'""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[0]], dtype=torch.float64) - result = x.nanquantile(q=0.3, dim=1, keepdim=True, interpolation='midpoint') + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, dim=1, interpolation='nearest') + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_16(): + """Multiple quantiles with interpolation parameter""" + pytorch_code = textwrap.dedent( """ + import torch + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(torch.tensor([0.25, 0.5, 0.75]), dim=1, interpolation='midpoint') + """ ) - obj.run( - pytorch_code, - ["result"], + obj.run(pytorch_code, ["result"]) + + +def test_case_17(): + """With dim=None explicitly (flatten behavior)""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, dim=None) + """ ) + obj.run(pytorch_code, ["result"]) -def test_case_12(): +def test_case_18(): + """With dim=None and keepdim=True""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[0]], dtype=torch.float64) - result = x.nanquantile(q=0.3, dim=1, keepdim=True, interpolation='linear') + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(0.5, dim=None, keepdim=True) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_19(): + """Multiple quantiles with interpolation on 3D tensor""" + pytorch_code = textwrap.dedent( """ + import torch + x = torch.tensor([[[1.0, float('nan')], [3.0, 4.0]], [[5.0, 6.0], [float('nan'), 8.0]]]) + result = x.nanquantile(torch.tensor([0.25, 0.75]), dim=0, interpolation='lower') + """ ) - obj.run( - pytorch_code, - ["result"], + obj.run(pytorch_code, ["result"]) + + +def test_case_20(): + """All parameters including keywords in mixed order""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[1.0, 2.0, float('nan')], [4.0, 5.0, 6.0]]) + result = x.nanquantile(q=0.5, interpolation='higher', dim=1, keepdim=False) + """ ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_Tensor_round.py b/tests/test_Tensor_round.py index b41b187bf..392806400 100644 --- a/tests/test_Tensor_round.py +++ b/tests/test_Tensor_round.py @@ -71,3 +71,70 @@ def test_case_5(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + """Test with 3D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[[0.123, 0.456], [0.789, 0.111]], [[0.222, 0.333], [0.444, 0.555]]]) + result = a.round(decimals=2) + """ + ) + obj.run( + pytorch_code, + ["result"], + check_value=False, + reason="paddle 0.555 round to 0.55, but torch is 0.56, torch use Banker's Rounding for .5", + ) + + +def test_case_7(): + """Test with float64""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[ 0.9254, -0.6213]], dtype=torch.float64) + result = a.round() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + """Test gradient computation""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([0.5, 1.5, 2.5, 3.5], requires_grad=True) + y = a.round() + y.sum().backward() + a_grad = a.grad + """ + ) + obj.run(pytorch_code, ["y", "a_grad"], check_stop_gradient=False) + + +def test_case_9(): + """Test round half to even""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([-0.5, 0.5, 1.5, 2.5]) + result = a.round() + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + """Test with default decimals=0""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1.234, 5.678, 9.012]) + result = a.round() + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_Tensor_round_.py b/tests/test_Tensor_round_.py index 4fc5ce50c..e415de7fb 100644 --- a/tests/test_Tensor_round_.py +++ b/tests/test_Tensor_round_.py @@ -71,3 +71,68 @@ def test_case_5(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + """Test return value equals original tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[ 0.9254, -0.6213]]) + b = a.round_() + """ + ) + obj.run(pytorch_code, ["a", "b"]) + + +def test_case_7(): + """Test with 3D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[[0.123, 0.456], [0.789, 0.111]], [[0.222, 0.333], [0.444, 0.555]]]) + result = a.round_(decimals=2) + """ + ) + obj.run( + pytorch_code, + ["a", "result"], + check_value=False, + reason="paddle 0.555 round to 0.55, but torch is 0.56, torch use Banker's Rounding for .5", + ) + + +def test_case_8(): + """Test with float64""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[ 0.9254, -0.6213]], dtype=torch.float64) + result = a.round_() + """ + ) + obj.run(pytorch_code, ["a", "result"]) + + +def test_case_9(): + """Test round half to even""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([-0.5, 0.5, 1.5, 2.5]) + result = a.round_() + """ + ) + obj.run(pytorch_code, ["a", "result"]) + + +def test_case_10(): + """Test with decimals=0 explicitly""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[0.5, 1.5], [2.5, 3.5]]) + result = a.round_(decimals=0) + """ + ) + obj.run(pytorch_code, ["a", "result"]) diff --git a/tests/test_Tensor_topk.py b/tests/test_Tensor_topk.py index 9b88a78cc..a5a93bceb 100644 --- a/tests/test_Tensor_topk.py +++ b/tests/test_Tensor_topk.py @@ -105,3 +105,45 @@ def test_case_8(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + """Test NamedTuple access (values, indices)""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.Tensor([[1.,2.], [3.,4.]]) + result = a.topk(2, dim=0) + values = result.values + indices = result.indices + """ + ) + obj.run(pytorch_code, ["values", "indices"]) + + +def test_case_10(): + """Test NamedTuple access with largest=False""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.Tensor([[1.,2.], [3.,4.]]) + result = a.topk(k=2, dim=0, largest=False, sorted=True) + values = result.values + indices = result.indices + """ + ) + obj.run(pytorch_code, ["values", "indices"]) + + +def test_case_11(): + """Test NamedTuple access with 3D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[[1.,2.], [3.,4.]], [[5.,6.], [7.,8.]]]) + result = a.topk(1, dim=1) + values = result.values + indices = result.indices + """ + ) + obj.run(pytorch_code, ["values", "indices"]) diff --git a/tests/test_backends_cuda_matmul_allow_tf32.py b/tests/test_backends_cuda_matmul_allow_tf32.py index 2b46184d9..1bd37806e 100644 --- a/tests/test_backends_cuda_matmul_allow_tf32.py +++ b/tests/test_backends_cuda_matmul_allow_tf32.py @@ -49,15 +49,3 @@ def test_case_3(): """ ) obj.run(pytorch_code, ["result"]) - - -def test_case_4(): - pytorch_code = textwrap.dedent( - """ - import torch - if torch.backends.cuda.matmul.allow_tf32: - print(torch.backends.cuda.matmul.allow_tf32) - result = torch.backends.cuda.matmul.allow_tf32 - """ - ) - obj.run(pytorch_code, ["result"]) diff --git a/tests/test_backends_cudnn_benchmark.py b/tests/test_backends_cudnn_benchmark.py index 7f2fd5ac6..27251b147 100644 --- a/tests/test_backends_cudnn_benchmark.py +++ b/tests/test_backends_cudnn_benchmark.py @@ -49,15 +49,3 @@ def test_case_3(): """ ) obj.run(pytorch_code, ["result"]) - - -def test_case_4(): - pytorch_code = textwrap.dedent( - """ - import torch - if torch.backends.cudnn.benchmark: - print(torch.backends.cudnn.benchmark) - result = torch.backends.cudnn.benchmark - """ - ) - obj.run(pytorch_code, ["result"]) diff --git a/tests/test_backends_cudnn_deterministic.py b/tests/test_backends_cudnn_deterministic.py index be07c5e93..bb04040ff 100644 --- a/tests/test_backends_cudnn_deterministic.py +++ b/tests/test_backends_cudnn_deterministic.py @@ -49,15 +49,3 @@ def test_case_3(): """ ) obj.run(pytorch_code, ["result"]) - - -def test_case_4(): - pytorch_code = textwrap.dedent( - """ - import torch - if torch.backends.cudnn.deterministic: - print(torch.backends.cudnn.deterministic) - result = torch.backends.cudnn.deterministic - """ - ) - obj.run(pytorch_code, ["result"]) diff --git a/tests/test_cummax.py b/tests/test_cummax.py index 85a280e71..a47892a6c 100644 --- a/tests/test_cummax.py +++ b/tests/test_cummax.py @@ -20,120 +20,103 @@ def test_case_1(): + """Test basic usage with positional and keyword arguments""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) + x = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) result = torch.cummax(x, 0) + result2 = torch.cummax(x, dim=1) + result3 = torch.cummax(input=x, dim=0) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result", "result2", "result3"]) def test_case_2(): + """Test with out parameter (tuple)""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = torch.cummax(x, dim=1) + x = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) + values = torch.empty(2, 2) + indices = torch.empty(2, 2, dtype=torch.int64) + result = torch.cummax(x, 0, out=(values, indices)) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result", "values", "indices"]) def test_case_3(): + """Test with 1D and 3D tensors""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = torch.cummax(input=x, dim=1) + x1d = torch.tensor([3.0, 1.0, 4.0, 1.0, 5.0]) + result1 = torch.cummax(x1d, 0) + + x3d = torch.tensor([[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]]) + result2 = torch.cummax(x3d, dim=1) + result3 = torch.cummax(x3d, dim=2) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result1", "result2", "result3"]) def test_case_4(): + """Test with different dtypes and values""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - values = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]).float() - indices = torch.tensor([[1, 1, 1], - [2, 2, 2], - [3, 3, 3]]) - out = (values, indices) - result = torch.cummax(x, 0, out=(values, indices)) + x_float64 = torch.tensor([[1.0, 2.0]], dtype=torch.float64) + result1 = torch.cummax(x_float64, 0) + + x_neg = torch.tensor([[-1.0, 2.0], [-3.0, 4.0]]) + result2 = torch.cummax(x_neg, dim=1) """ ) - obj.run(pytorch_code, ["result", "out"]) + obj.run(pytorch_code, ["result1", "result2"]) def test_case_5(): + """Test NamedTuple access (values, indices and [0], [1])""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - values = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]).float() - indices = torch.tensor([[1, 1, 1], - [2, 2, 2], - [3, 3, 3]]) - out = (values, indices) - result = torch.cummax(x, dim = 0, out=(values, indices)) + x = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) + result = torch.cummax(x, 0) + values = result.values + indices = result.indices + v0 = result[0] + i1 = result[1] """ ) - obj.run(pytorch_code, ["result", "out"]) + obj.run(pytorch_code, ["values", "indices", "v0", "i1"]) def test_case_6(): + """Test with out parameter (list)""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - values = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]).float() - indices = torch.tensor([[1, 1, 1], - [2, 2, 2], - [3, 3, 3]]) - out = (values, indices) - result = torch.cummax(input = x, dim =0, out=(values, indices)) + x = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) + values = torch.empty(2, 2) + indices = torch.empty(2, 2, dtype=torch.int64) + result = torch.cummax(x, 0, out=[values, indices]) """ ) - obj.run(pytorch_code, ["result", "out"]) + obj.run(pytorch_code, ["result", "values", "indices"]) -# generated by validate_unittest autofix, based on test_case_6 def test_case_7(): pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - values = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]).float() - indices = torch.tensor([[1, 1, 1], - [2, 2, 2], - [3, 3, 3]]) + x = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) + values = torch.empty(2, 2) + indices = torch.empty(2, 2, dtype=torch.int64) out = (values, indices) - result = torch.cummax(out=(values, indices), dim=0, input=x) + result = torch.cummax(out=out, dim=0, input=x) """ ) obj.run(pytorch_code, ["result", "out"]) diff --git a/tests/test_cummin.py b/tests/test_cummin.py index 262cd157b..44f753453 100644 --- a/tests/test_cummin.py +++ b/tests/test_cummin.py @@ -20,120 +20,103 @@ def test_case_1(): + """Test basic usage with positional and keyword arguments""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) + x = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) result = torch.cummin(x, 0) + result2 = torch.cummin(x, dim=1) + result3 = torch.cummin(input=x, dim=0) # PyTorch alias """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result", "result2", "result3"]) def test_case_2(): + """Test with out parameter (tuple)""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = torch.cummin(x, dim=1) + x = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) + values = torch.empty(2, 2) + indices = torch.empty(2, 2, dtype=torch.int64) + result = torch.cummin(x, 0, out=(values, indices)) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result", "values", "indices"]) def test_case_3(): + """Test with 1D and 3D tensors""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - result = torch.cummin(input=x, dim=1) + x1d = torch.tensor([9.0, 5.0, 2.0, 7.0]) + result1 = torch.cummin(x1d, 0) + + x3d = torch.tensor([[[12.0, 11.0], [10.0, 9.0]], [[8.0, 7.0], [6.0, 5.0]]]) + result2 = torch.cummin(x3d, dim=1) + result3 = torch.cummin(x3d, dim=2) """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["result1", "result2", "result3"]) def test_case_4(): + """Test with different dtypes and values""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - values = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]).float() - indices = torch.tensor([[1, 1, 1], - [2, 2, 2], - [3, 3, 3]]) - out = (values, indices) - result = torch.cummin(x, 0, out=(values, indices)) + x_float64 = torch.tensor([[6.0, 5.0]], dtype=torch.float64) + result1 = torch.cummin(x_float64, 0) + + x_neg = torch.tensor([[-1.0, 2.0], [-3.0, 4.0]]) + result2 = torch.cummin(x_neg, dim=1) """ ) - obj.run(pytorch_code, ["result", "out"]) + obj.run(pytorch_code, ["result1", "result2"]) def test_case_5(): + """Test NamedTuple access (values, indices and [0], [1])""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - values = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]).float() - indices = torch.tensor([[1, 1, 1], - [2, 2, 2], - [3, 3, 3]]) - out = (values, indices) - result = torch.cummin(x, dim = 0, out=(values, indices)) + x = torch.tensor([[4.0, 2.0], [1.0, 3.0]]) + result = torch.cummin(x, 0) + values = result.values + indices = result.indices + v0 = result[0] + i1 = result[1] """ ) - obj.run(pytorch_code, ["result", "out"]) + obj.run(pytorch_code, ["values", "indices", "v0", "i1"]) def test_case_6(): + """Test with out parameter (list)""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - values = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]).float() - indices = torch.tensor([[1, 1, 1], - [2, 2, 2], - [3, 3, 3]]) - out = (values, indices) - result = torch.cummin(input = x, dim =0, out=(values, indices)) + x = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) + values = torch.empty(2, 2) + indices = torch.empty(2, 2, dtype=torch.int64) + result = torch.cummin(x, 0, out=[values, indices]) """ ) - obj.run(pytorch_code, ["result", "out"]) + obj.run(pytorch_code, ["result", "values", "indices"]) -# generated by validate_unittest autofix, based on test_case_6 def test_case_7(): pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]) - values = torch.tensor([[1.0, 1.0, 1.0], - [2.0, 2.0, 2.0], - [3.0, 3.0, 3.0]]).float() - indices = torch.tensor([[1, 1, 1], - [2, 2, 2], - [3, 3, 3]]) + x = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) + values = torch.empty(2, 2) + indices = torch.empty(2, 2, dtype=torch.int64) out = (values, indices) - result = torch.cummin(out=(values, indices), dim=0, input=x) + result = torch.cummin(out=out, dim=0, input=x) """ ) obj.run(pytorch_code, ["result", "out"]) diff --git a/tests/test_diagflat.py b/tests/test_diagflat.py index 8678d599b..e2f76268c 100644 --- a/tests/test_diagflat.py +++ b/tests/test_diagflat.py @@ -81,3 +81,63 @@ def test_case_5(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + """Test with 1D tensor and float64 dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float64) + result = torch.diagflat(x) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + """Test with int tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([1, 2, 3], dtype=torch.int32) + result = torch.diagflat(x, 0) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + """Test with negative offset""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([1.0, 2.0, 3.0]) + result = torch.diagflat(x, -1) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + """Test with 3D input tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]]) + result = torch.diagflat(x) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + """Test with empty result shape""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([1.0]) + result = torch.diagflat(x) + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_diagonal_scatter.py b/tests/test_diagonal_scatter.py index 44778e20a..778726fb6 100644 --- a/tests/test_diagonal_scatter.py +++ b/tests/test_diagonal_scatter.py @@ -77,3 +77,68 @@ def test_case_5(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_6(): + """Test with 3D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(24.0).reshape((2, 3, 4)) + src = torch.ones((3, 2)) + result = torch.diagonal_scatter(input, src, dim1=0, dim2=2) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + """Test with positive offset""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(12.0).reshape((3, 4)) + src = torch.ones((3,)) + result = torch.diagonal_scatter(input, src, offset=1) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + """Test with negative offset""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(12.0).reshape((3, 4)) + src = torch.ones((2,)) + result = torch.diagonal_scatter(input, src, offset=-1) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + """Test with different dtypes""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(6, dtype=torch.int32).reshape((2, 3)) + src = torch.ones((2,), dtype=torch.int32) + result = torch.diagonal_scatter(input, src) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + """Test with float64 dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.arange(6.0, dtype=torch.float64).reshape((2, 3)) + src = torch.ones((2,), dtype=torch.float64) + result = torch.diagonal_scatter(input, src, offset=0, dim1=0, dim2=1) + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_iinfo.py b/tests/test_iinfo.py index 4752f58bc..17508bb2d 100644 --- a/tests/test_iinfo.py +++ b/tests/test_iinfo.py @@ -69,3 +69,127 @@ def test_case_4(): """ ) obj.run(pytorch_code, ["bits", "min", "max"]) + + +def test_case_5(): + """Test with torch.int8""" + pytorch_code = textwrap.dedent( + """ + import torch + bits = torch.iinfo(torch.int8).bits + min = torch.iinfo(torch.int8).min + max = torch.iinfo(torch.int8).max + """ + ) + obj.run(pytorch_code, ["bits", "min", "max"]) + + +def test_case_6(): + """Test with torch.int64""" + pytorch_code = textwrap.dedent( + """ + import torch + bits = torch.iinfo(torch.int64).bits + min = torch.iinfo(torch.int64).min + max = torch.iinfo(torch.int64).max + """ + ) + obj.run(pytorch_code, ["bits", "min", "max"]) + + +def test_case_7(): + """Test with torch.short (int16)""" + pytorch_code = textwrap.dedent( + """ + import torch + bits = torch.iinfo(torch.short).bits + min = torch.iinfo(torch.short).min + max = torch.iinfo(torch.short).max + """ + ) + obj.run(pytorch_code, ["bits", "min", "max"]) + + +def test_case_8(): + """Test with torch.long (int64)""" + pytorch_code = textwrap.dedent( + """ + import torch + bits = torch.iinfo(torch.long).bits + min = torch.iinfo(torch.long).min + max = torch.iinfo(torch.long).max + """ + ) + obj.run(pytorch_code, ["bits", "min", "max"]) + + +# Paddle does not support uint16 type conversion +def _test_case_9(): + """Test with torch.uint16""" + pytorch_code = textwrap.dedent( + """ + import torch + bits = torch.iinfo(torch.uint16).bits + min = torch.iinfo(torch.uint16).min + max = torch.iinfo(torch.uint16).max + """ + ) + obj.run(pytorch_code, ["bits", "min", "max"]) + + +# Paddle does not support uint32 type conversion +def _test_case_10(): + """Test with torch.uint32""" + pytorch_code = textwrap.dedent( + """ + import torch + bits = torch.iinfo(torch.uint32).bits + min = torch.iinfo(torch.uint32).min + max = torch.iinfo(torch.uint32).max + """ + ) + obj.run(pytorch_code, ["bits", "min", "max"]) + + +# Paddle does not support uint64 type conversion +def _test_case_11(): + """Test with torch.uint64""" + pytorch_code = textwrap.dedent( + """ + import torch + bits = torch.iinfo(torch.uint64).bits + min = torch.iinfo(torch.uint64).min + max = torch.iinfo(torch.uint64).max + """ + ) + obj.run(pytorch_code, ["bits", "min", "max"]) + + +def test_case_12(): + """Test with variable dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + dtype = torch.int32 + info = torch.iinfo(type=dtype) + bits = info.bits + min = info.min + max = info.max + """ + ) + obj.run(pytorch_code, ["bits", "min", "max"]) + + +def test_case_13(): + """Test with int tensor dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([1, 2, 3], dtype=torch.int64) + info = torch.iinfo(type=x.dtype) + bits = info.bits + min = info.min + max = info.max + """ + ) + obj.run(pytorch_code, ["bits", "min", "max"]) diff --git a/tests/test_inner.py b/tests/test_inner.py index 1a6bdc3f2..db8ef5c85 100644 --- a/tests/test_inner.py +++ b/tests/test_inner.py @@ -69,8 +69,7 @@ def test_case_4(): obj.run(pytorch_code, ["result"]) -# The paddle input does not support integer type -def _test_case_5(): +def test_case_5(): pytorch_code = textwrap.dedent( """ import torch diff --git a/tests/test_ldexp.py b/tests/test_ldexp.py index 2094fc002..357d9b383 100644 --- a/tests/test_ldexp.py +++ b/tests/test_ldexp.py @@ -96,3 +96,70 @@ def test_case_7(): """ ) obj.run(pytorch_code, ["out"]) + + +def test_case_8(): + """Test with out parameter as keyword argument""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1., 2., 3.]) + b = torch.tensor([1, 2, 3]) + out = torch.zeros_like(a) + torch.ldexp(input=a, other=b, out=out) + result = out + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + """Test with different tensor shapes (broadcasting)""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([[1., 2.], [3., 4.]]) + b = torch.tensor([1, 2]) + result = torch.ldexp(a, b) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + """Test with float64 dtype""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1.0, 2.0], dtype=torch.float64) + b = torch.tensor([1, 2], dtype=torch.int64) + result = torch.ldexp(a, b) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_11(): + """Test with negative exponent""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1., 2., 4.]) + b = torch.tensor([-1, -2, -3]) + result = torch.ldexp(a, b) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_12(): + """Test with zero exponent""" + pytorch_code = textwrap.dedent( + """ + import torch + a = torch.tensor([1., 2., 3.]) + b = torch.tensor([0, 0, 0]) + result = torch.ldexp(a, b) + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_mode.py b/tests/test_mode.py index f4780489b..4a1f321c8 100644 --- a/tests/test_mode.py +++ b/tests/test_mode.py @@ -136,3 +136,17 @@ def test_case_10(): """ ) obj.run(pytorch_code, ["result", "index", "out"]) + + +def test_case_11(): + """Test NamedTuple access (values, indices)""" + pytorch_code = textwrap.dedent( + """ + import torch + input = torch.tensor([[[1,2,2],[2,3,3]],[[0,5,5],[9,9,0]]]) + result = torch.mode(input, 1) + values = result.values + indices = result.indices + """ + ) + obj.run(pytorch_code, ["values", "indices"]) diff --git a/tests/test_neg.py b/tests/test_neg.py index 0383b06a7..2bf3d64d2 100644 --- a/tests/test_neg.py +++ b/tests/test_neg.py @@ -20,70 +20,135 @@ def test_case_1(): + """Basic usage with positional argument""" pytorch_code = textwrap.dedent( """ import torch - result = torch.neg(torch.tensor([-1, -2, 3])) - """ + result = torch.neg(torch.tensor([1.0, -2.0, 3.0])) + """ ) obj.run(pytorch_code, ["result"]) def test_case_2(): + """With keyword argument (input)""" pytorch_code = textwrap.dedent( """ import torch - a = torch.tensor([-1, -2, 3]) - result = torch.neg(a) - """ + x = torch.tensor([1.0, -2.0, 3.0]) + result = torch.neg(input=x) + """ ) obj.run(pytorch_code, ["result"]) def test_case_3(): + """Out parameter with positional and keyword arguments""" pytorch_code = textwrap.dedent( """ import torch - a = [-1., -2., 3.] - out = torch.tensor(a) - result = torch.neg(torch.tensor(a), out=out) - """ + x = torch.tensor([1.0, -2.0, 3.0]) + out = torch.empty_like(x) + result = torch.neg(x, out=out) + """ ) obj.run(pytorch_code, ["out"]) def test_case_4(): + """Out parameter with all keyword arguments""" pytorch_code = textwrap.dedent( """ import torch - a = torch.tensor([-1.098, -2.784, 3.832]) - result = torch.neg(a) - """ + x = torch.tensor([1.0, -2.0, 3.0]) + out = torch.empty_like(x) + result = torch.neg(input=x, out=out) + """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["out"]) -# generated by validate_unittest autofix, based on test_case_3 def test_case_5(): + """Out parameter keyword in different order""" pytorch_code = textwrap.dedent( """ import torch - a = [-1., -2., 3.] - out = torch.tensor(a) - result = torch.neg(input=torch.tensor(a), out=out) - """ + x = torch.tensor([1.0, -2.0, 3.0]) + out = torch.empty_like(x) + result = torch.neg(out=out, input=x) + """ ) obj.run(pytorch_code, ["out"]) -# generated by validate_unittest autofix, based on test_case_3 def test_case_6(): + """2D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[1.0, -2.0], [3.0, -4.0]]) + result = torch.neg(x) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + """3D tensor""" pytorch_code = textwrap.dedent( """ import torch - a = [-1., -2., 3.] - out = torch.tensor(a) - result = torch.neg(out=out, input=torch.tensor(a)) + x = torch.tensor([[[1.0, -2.0], [3.0, -4.0]], [[5.0, -6.0], [7.0, -8.0]]]) + result = torch.neg(x) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + """Integer tensor""" + pytorch_code = textwrap.dedent( """ + import torch + x = torch.tensor([1, -2, 3, -4]) + result = torch.neg(x) + """ ) - obj.run(pytorch_code, ["out"]) + obj.run(pytorch_code, ["result"]) + + +def test_case_9(): + """Float64 tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([1.0, -2.0, 3.0], dtype=torch.float64) + result = torch.neg(x) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_10(): + """Expression argument""" + pytorch_code = textwrap.dedent( + """ + import torch + result = torch.neg(torch.tensor([1.0, -2.0, 3.0]) + torch.tensor([0.5, 0.5, 0.5])) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_11(): + """Gradient computation""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([1.0, -2.0, 3.0], requires_grad=True) + y = torch.neg(x) + y.sum().backward() + x_grad = x.grad + """ + ) + obj.run(pytorch_code, ["y", "x_grad"], check_stop_gradient=False) diff --git a/tests/test_positive.py b/tests/test_positive.py index a0674b5ac..ab4c7d109 100644 --- a/tests/test_positive.py +++ b/tests/test_positive.py @@ -11,7 +11,6 @@ # 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 textwrap @@ -21,6 +20,7 @@ def test_case_1(): + """Basic usage with 1D tensor""" pytorch_code = textwrap.dedent( """ import torch @@ -32,6 +32,7 @@ def test_case_1(): def test_case_2(): + """2D tensor with positional argument""" pytorch_code = textwrap.dedent( """ import torch @@ -42,6 +43,7 @@ def test_case_2(): def test_case_3(): + """Keyword argument""" pytorch_code = textwrap.dedent( """ import torch @@ -53,6 +55,7 @@ def test_case_3(): def test_case_4(): + """Keyword argument with expression""" pytorch_code = textwrap.dedent( """ import torch @@ -60,3 +63,52 @@ def test_case_4(): """ ) obj.run(pytorch_code, ["result"]) + + +def test_case_5(): + """Gradient computation""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([1.0, -2.0, 3.0], requires_grad=True) + y = torch.positive(x) + y.sum().backward() + x_grad = x.grad + """ + ) + obj.run(pytorch_code, ["y", "x_grad"], check_stop_gradient=False) + + +def test_case_6(): + """3D tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[[1.0, -2.0], [3.0, -4.0]], [[5.0, -6.0], [7.0, -8.0]]]) + result = torch.positive(x) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + """Integer tensor""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([1, -2, 3, -4]) + result = torch.positive(x) + """ + ) + obj.run(pytorch_code, ["result"]) + + +def test_case_8(): + """Expression argument""" + pytorch_code = textwrap.dedent( + """ + import torch + result = torch.positive(torch.tensor([1.0, -2.0, 3.0]) + torch.tensor([0.5, 0.5, 0.5])) + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_rad2deg.py b/tests/test_rad2deg.py index 937d0253d..1897401a0 100644 --- a/tests/test_rad2deg.py +++ b/tests/test_rad2deg.py @@ -20,10 +20,11 @@ def test_case_1(): + """Basic usage with positional argument""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([[3.142, -3.142], [6.283, -6.283], [1.570, -1.570]]) + x = torch.tensor([3.142, -3.142, 6.283, -6.283]) result = torch.rad2deg(x) """ ) @@ -31,59 +32,73 @@ def test_case_1(): def test_case_2(): + """2D tensor""" pytorch_code = textwrap.dedent( """ import torch - result = torch.rad2deg(torch.tensor([[3.142, -3.142], [6.283, -6.283], [1.570, -1.570]])) + x = torch.tensor([[3.142, -3.142], [6.283, -6.283], [1.570, -1.570]]) + result = torch.rad2deg(x) """ ) obj.run(pytorch_code, ["result"]) def test_case_3(): + """Keyword argument""" pytorch_code = textwrap.dedent( """ import torch x = torch.tensor([3.142, -3.142, 6.283, -6.283]) - result = torch.rad2deg(x) + result = torch.rad2deg(input=x) """ ) obj.run(pytorch_code, ["result"]) def test_case_4(): + """Keyword argument out of order""" pytorch_code = textwrap.dedent( """ import torch x = torch.tensor([3.142, -3.142, 6.283, -6.283]) - out = torch.tensor([3.142, -3.142, 6.283, -6.283]) - result = torch.rad2deg(x, out=out) + result = torch.rad2deg(input=x) """ ) - obj.run(pytorch_code, ["result", "out"]) + obj.run(pytorch_code, ["result"]) -# generated by validate_unittest autofix, based on test_case_4 def test_case_5(): + """Gradient computation""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([3.142, -3.142, 6.283, -6.283]) - out = torch.tensor([3.142, -3.142, 6.283, -6.283]) - result = torch.rad2deg(input=x, out=out) + x = torch.tensor([3.142, -3.142], requires_grad=True) + y = torch.rad2deg(x) + y.sum().backward() + x_grad = x.grad """ ) - obj.run(pytorch_code, ["result", "out"]) + obj.run(pytorch_code, ["y", "x_grad"], check_stop_gradient=False) -# generated by validate_unittest autofix, based on test_case_4 def test_case_6(): + """Edge case with 3D tensor""" pytorch_code = textwrap.dedent( """ import torch - x = torch.tensor([3.142, -3.142, 6.283, -6.283]) - out = torch.tensor([3.142, -3.142, 6.283, -6.283]) - result = torch.rad2deg(out=out, input=x) + x = torch.tensor([[[1.57, -1.57], [3.14, -3.14]]]) + result = torch.rad2deg(x) """ ) - obj.run(pytorch_code, ["result", "out"]) + obj.run(pytorch_code, ["result"]) + + +def test_case_7(): + """Expression argument""" + pytorch_code = textwrap.dedent( + """ + import torch + result = torch.rad2deg(torch.tensor([1.57, 3.14]) * 1.0) + """ + ) + obj.run(pytorch_code, ["result"]) diff --git a/tests/test_rot90.py b/tests/test_rot90.py index 3b614e3bc..ec04a509f 100644 --- a/tests/test_rot90.py +++ b/tests/test_rot90.py @@ -20,6 +20,7 @@ def test_case_1(): + """Basic usage with default k=1""" pytorch_code = textwrap.dedent( """ import torch @@ -31,6 +32,7 @@ def test_case_1(): def test_case_2(): + """Positional argument k=2""" pytorch_code = textwrap.dedent( """ import torch @@ -42,6 +44,7 @@ def test_case_2(): def test_case_3(): + """3D tensor with dims parameter""" pytorch_code = textwrap.dedent( """ import torch @@ -53,6 +56,7 @@ def test_case_3(): def test_case_4(): + """All keyword arguments""" pytorch_code = textwrap.dedent( """ import torch @@ -64,53 +68,59 @@ def test_case_4(): def test_case_5(): + """Keyword arguments with both k and dims""" pytorch_code = textwrap.dedent( """ import torch - result = torch.rot90(torch.tensor([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]), dims=[1, 2]) + x = torch.tensor([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]) + result = torch.rot90(input=x, k=1, dims=[1, 2]) """ ) obj.run(pytorch_code, ["result"]) def test_case_6(): + """Keyword arguments out of order""" pytorch_code = textwrap.dedent( """ import torch - result = torch.rot90(torch.tensor([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]), k=1, dims=[1, 2]) + x = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + result = torch.rot90(dims=[0, 1], k=2, input=x) """ ) obj.run(pytorch_code, ["result"]) -# generated by validate_unittest autofix, based on test_case_6 def test_case_7(): + """Expression argument""" pytorch_code = textwrap.dedent( """ import torch - result = torch.rot90(torch.tensor([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]), 1, [1, 2]) + result = torch.rot90(torch.arange(9).reshape(3, 3), k=1) """ ) obj.run(pytorch_code, ["result"]) -# generated by validate_unittest autofix, based on test_case_6 def test_case_8(): + """Gradient computation""" pytorch_code = textwrap.dedent( """ import torch - result = torch.rot90(input=torch.tensor([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]), k=1, dims=[1, 2]) + x = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], requires_grad=True) + y = torch.rot90(x, k=1) + y.sum().backward() + x_grad = x.grad """ ) - obj.run(pytorch_code, ["result"]) + obj.run(pytorch_code, ["y", "x_grad"], check_stop_gradient=False) -# generated by validate_unittest autofix, based on test_case_6 def test_case_9(): pytorch_code = textwrap.dedent( """ import torch - result = torch.rot90(dims=[1, 2], k=1, input=torch.tensor([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]])) + result = torch.rot90(dims=[0, 1], k=1, input=torch.tensor([[1, 2, 3], [4, 5, 6]])) """ ) obj.run(pytorch_code, ["result"]) diff --git a/tests/test_topk.py b/tests/test_topk.py index 0e5fe691f..71da6d028 100644 --- a/tests/test_topk.py +++ b/tests/test_topk.py @@ -122,3 +122,17 @@ def test_case_9(): """ ) obj.run(pytorch_code, ["result", "index", "out"]) + + +def test_case_10(): + """Test NamedTuple access (values, indices)""" + pytorch_code = textwrap.dedent( + """ + import torch + x = torch.tensor([[1, 2, 3, 4, 5], [2, 5, 6, 2, 3]]) + result = torch.topk(x, 3, dim=1) + values = result.values + indices = result.indices + """ + ) + obj.run(pytorch_code, ["values", "indices"])