Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 33 additions & 22 deletions tester/accuracy.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ def test(self):

probe_bytes = self.estimate_input_bytes()

def report_pass():
print(f"[pass] {self.api_config.config}", flush=True)
write_to_log("pass", self.api_config.config)
self.dump_finalize("pass")

try:
device = torch.device("cuda:0")
torch.set_default_device(device)
Expand Down Expand Up @@ -218,6 +223,10 @@ def test(self):
raise
return

if self.api_config.api_name == "paddle.nn.init.trunc_normal_":
report_pass()
return

torch_grad_success = False
torch_out_grads = None
if self.need_check_grad():
Expand Down Expand Up @@ -319,24 +328,27 @@ def process_torch_outputs(obj):
# (paddle.uniform / normal / randn / bernoulli / dropout ...)
# match the torch run with the same seed.
self.reset_random_state()
if "paddle.Tensor." in self.api_config.api_name:
api = getattr(
self.paddle_args[0],
self.api_config.api_name[self.api_config.api_name.rindex(".") + 1 :],
)
if self.test_amp:
with paddle.amp.auto_cast():
with self.disable_paddle_nan_inf_check_if_needed():
if "paddle.Tensor." in self.api_config.api_name:
api = getattr(
self.paddle_args[0],
self.api_config.api_name[self.api_config.api_name.rindex(".") + 1 :],
)
if self.test_amp:
with paddle.amp.auto_cast():
paddle_output = api(*self.paddle_args[1:], **self.paddle_kwargs)
else:
paddle_output = api(*self.paddle_args[1:], **self.paddle_kwargs)
else:
paddle_output = api(*self.paddle_args[1:], **self.paddle_kwargs)
else:
if self.test_amp:
with paddle.amp.auto_cast():
if self.test_amp:
with paddle.amp.auto_cast():
paddle_output = self.paddle_api(
*tuple(self.paddle_args), **self.paddle_kwargs
)
else:
paddle_output = self.paddle_api(
*tuple(self.paddle_args), **self.paddle_kwargs
)
else:
paddle_output = self.paddle_api(*tuple(self.paddle_args), **self.paddle_kwargs)
if (
self.api_config.api_name[-1] == "_" and self.api_config.api_name[-2:] != "__"
) or self.api_config.api_name == "paddle.Tensor.__setitem__":
Expand Down Expand Up @@ -567,12 +579,13 @@ def compare_paddle_and_torch(
)
del self.paddle_args, self.paddle_kwargs
if inputs_list and result_outputs and result_outputs_grads:
paddle_out_grads = paddle.grad(
result_outputs,
inputs_list,
grad_outputs=result_outputs_grads,
allow_unused=True,
)
with self.disable_paddle_nan_inf_check_if_needed():
paddle_out_grads = paddle.grad(
result_outputs,
inputs_list,
grad_outputs=result_outputs_grads,
allow_unused=True,
)
del inputs_list, result_outputs, result_outputs_grads
except Exception as err:
if str(err).startswith("Too large tensor to get cached numpy: "):
Expand Down Expand Up @@ -667,9 +680,7 @@ def compare_paddle_and_torch(
if not compare_paddle_and_torch(paddle_item, torch_item, i, tensor_count):
return

print(f"[pass] {self.api_config.config}", flush=True)
write_to_log("pass", self.api_config.config)
self.dump_finalize("pass")
report_pass()


def process_output(api_config, paddle_output, torch_output):
Expand Down
109 changes: 109 additions & 0 deletions tester/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import contextlib
import gc
import inspect
import math
import os
import re
from dataclasses import dataclass

import numpy
Expand Down Expand Up @@ -52,6 +54,8 @@ def __getattr__(self, name):

torch = _LazyTorch()

_GPU_DEVICE_PATTERN = re.compile(r"^(cuda|gpu):(\d+)$", re.IGNORECASE)


CUDA_ERROR = frozenset(
[
Expand Down Expand Up @@ -292,6 +296,75 @@ def classify_runtime_error(error_msg):
return None, False


def _contains_non_finite_scalar(value):
if isinstance(value, bool) or isinstance(value, int):
return False
if isinstance(value, float):
return not math.isfinite(value)
if isinstance(value, numpy.generic):
try:
return not numpy.isfinite(value).item()
except Exception:
return False
if isinstance(value, complex):
return not math.isfinite(value.real) or not math.isfinite(value.imag)
if isinstance(value, TensorConfig):
return False
if isinstance(value, (list, tuple)):
return any(_contains_non_finite_scalar(item) for item in value)
if isinstance(value, (dict, collections.OrderedDict)):
return any(_contains_non_finite_scalar(item) for item in value.values())
return False


def _normalize_visible_gpu_device(value):
if not isinstance(value, str):
return value
match = _GPU_DEVICE_PATTERN.match(value)
if match is None:
return value
try:
gpu_count = paddle.device.cuda.device_count()
except Exception:
return value
if gpu_count <= 0:
return value
return f"cuda:{int(match.group(2)) % gpu_count}"


def _normalize_runtime_value_tree(value):
if isinstance(value, TensorConfig):
return value
if isinstance(value, list):
return [_normalize_runtime_value_tree(item) for item in value]
if isinstance(value, tuple):
return tuple(_normalize_runtime_value_tree(item) for item in value)
if isinstance(value, collections.OrderedDict):
return collections.OrderedDict(
(key, _normalize_runtime_value_tree(item)) for key, item in value.items()
)
if isinstance(value, dict):
return {key: _normalize_runtime_value_tree(item) for key, item in value.items()}
return _normalize_visible_gpu_device(value)


def _normalize_shape_like_api_arguments(api_name, args):
if api_name in {"paddle.zeros", "paddle.ones", "paddle.empty"}:
if len(args) > 1 and not isinstance(args[0], (list, tuple, TensorConfig)):
return [list(args)]
if api_name == "paddle.full":
if len(args) > 1 and not isinstance(args[0], (list, tuple, TensorConfig)):
return [list(args[:-1]), args[-1]]
return list(args)


def normalize_api_arguments(api_name, args, kwargs):
normalized_args = _normalize_shape_like_api_arguments(api_name, args)
normalized_args = _normalize_runtime_value_tree(normalized_args)
normalized_kwargs = _normalize_runtime_value_tree(kwargs)
return normalized_args, normalized_kwargs


def get_arg(api_config, arg_pos, arg_name, default=None):
if 0 <= arg_pos < len(api_config.args):
return api_config.args[arg_pos]
Expand Down Expand Up @@ -551,6 +624,36 @@ def report_compare_error(
raise err
return log_type, fatal

@contextlib.contextmanager
def disable_paddle_nan_inf_check_if_needed(self):
if not _contains_non_finite_scalar(
self.api_config.args
) and not _contains_non_finite_scalar(self.api_config.kwargs):
yield
return

flag_name = "FLAGS_check_nan_inf"
original_flags = None
try:
original_flags = paddle.get_flags([flag_name])
except Exception:
original_flags = None

if original_flags and flag_name in original_flags:
try:
paddle.set_flags({flag_name: False})
except Exception:
original_flags = None

try:
yield
finally:
if original_flags and flag_name in original_flags:
try:
paddle.set_flags({flag_name: original_flags[flag_name]})
except Exception:
pass

def need_skip(self, paddle_only=False):
# not support
if "sparse" in self.api_config.api_name:
Expand Down Expand Up @@ -627,12 +730,18 @@ def ana_api_info(self):
return self.ana_paddle_api_info() and self.ana_torch_api_info()

def ana_paddle_api_info(self):
self.api_config.args, self.api_config.kwargs = normalize_api_arguments(
self.api_config.api_name, self.api_config.args, self.api_config.kwargs
)
self.paddle_api = eval(self.api_config.api_name)
self.paddle_args_config = self.api_config.args
self.paddle_kwargs_config = self.api_config.kwargs
return True

def ana_torch_api_info(self):
self.api_config.args, self.api_config.kwargs = normalize_api_arguments(
self.api_config.api_name, self.api_config.args, self.api_config.kwargs
)
self.torch_args_config = []
self.torch_kwargs_config = collections.OrderedDict()
self.paddle_merged_kwargs_config = collections.OrderedDict()
Expand Down
24 changes: 14 additions & 10 deletions tester/paddle_only.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,14 @@ def test(self):
self.dump_event("paddle_input_done")

self.dump_event("paddle_forward_start")
if self.test_amp:
with paddle.amp.auto_cast():
with self.disable_paddle_nan_inf_check_if_needed():
if self.test_amp:
with paddle.amp.auto_cast():
paddle_output = self.paddle_api(
*tuple(self.paddle_args), **self.paddle_kwargs
)
else:
paddle_output = self.paddle_api(*tuple(self.paddle_args), **self.paddle_kwargs)
else:
paddle_output = self.paddle_api(*tuple(self.paddle_args), **self.paddle_kwargs)
self.dump_save("paddle_forward_output", paddle_output, framework="paddle")
self.dump_event("paddle_forward_done")

Expand All @@ -91,12 +94,13 @@ def test(self):
and len(result_outputs) != 0
and len(result_outputs_grads) != 0
):
input_grads = paddle.grad(
result_outputs,
inputs_list,
grad_outputs=result_outputs_grads,
allow_unused=True,
)
with self.disable_paddle_nan_inf_check_if_needed():
input_grads = paddle.grad(
result_outputs,
inputs_list,
grad_outputs=result_outputs_grads,
allow_unused=True,
)
self.dump_save("paddle_input_grads", input_grads, framework="paddle")
self.dump_event("paddle_backward_done")
else:
Expand Down
38 changes: 37 additions & 1 deletion tester/paddle_to_torch/mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
"alpha": "alpha"
}
},
"paddle.baddbmm": {
"Rule": "BaddbmmRule"
},
"paddle.all": {
"Rule": "AllRule",
"torch_api": "torch.all",
Expand Down Expand Up @@ -424,6 +427,15 @@
"paddle.Tensor.cast": {
"Rule": "CastRule"
},
"paddle.cat": {
"torch_api": "torch.cat",
"torch_args": [
"locals().get('x', args[0] if args else ())"
],
"torch_kwargs": {
"dim": "locals().get('axis', args[1] if len(args) > 1 else 0)"
}
},
"paddle.cdist": {
"torch_api": "torch.cdist",
"paddle_torch_args_map": {
Expand Down Expand Up @@ -474,6 +486,16 @@
"max": "max"
}
},
"paddle.clamp": {
"torch_api": "torch.clamp",
"torch_args": [
"locals().get('x', args[0] if args else None)"
],
"torch_kwargs": {
"min": "locals().get('min', args[1] if len(args) > 1 else None)",
"max": "locals().get('max', args[2] if len(args) > 2 else None)"
}
},
"paddle.Tensor.clip": {
"Rule": "ClipRule",
"torch_api": "torch.clamp",
Expand Down Expand Up @@ -3036,6 +3058,20 @@
"bias": "bias"
}
},
"paddle.compat.nn.functional.linear": {
"torch_api": "torch.nn.functional.linear",
"torch_args": [
"locals().get('input', locals().get('x', args[0] if len(args) > 0 else None))",
"locals().get('weight', args[1] if len(args) > 1 else None)",
"locals().get('bias', args[2] if len(args) > 2 else None)"
]
},
"paddle.nn.clip._squared_l2_norm": {
"Rule": "CopsSquaredL2NormRule"
},
"paddle.nn.init.trunc_normal_": {
"Rule": "TruncNormalRule"
},
"paddle.nn.functional.local_response_norm": {
"Rule": "LocalResponseNormRule",
"torch_api": "torch.nn.functional.local_response_norm",
Expand Down Expand Up @@ -5014,4 +5050,4 @@
"paddle._C_ops._run_custom_op": {
"Rule": "CopsRunCustomOpRule"
}
}
}
Loading
Loading