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
31 changes: 25 additions & 6 deletions engineV2.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,6 @@ def validate_gpu_options(options) -> tuple:
"expected -1 or a positive integer"
)
if getattr(options, "accuracy_stable_dual_gpu", False):
if getattr(options, "test_cpu", False):
raise ValueError("--accuracy_stable_dual_gpu=True does not support --test_cpu=True")
if options.num_gpus < 2 or options.num_gpus % 2:
raise ValueError("--accuracy_stable_dual_gpu=True requires an even --num_gpus")
if options.num_workers_per_gpu != 1:
Expand All @@ -462,6 +460,29 @@ def normalize_accuracy_stable_dual_gpu_options(options):
options.accuracy_stable = True


def _mode_runs_torch_gpu_reference(options):
"""只有执行 Torch reference 的模式才要求保留 GPU 运行时。"""
return any(
getattr(options, mode, False)
for mode in (
"accuracy",
"accuracy_stable",
"accuracy_stable_dual_gpu",
"torch_gpu_performance",
"paddle_torch_gpu_performance",
)
)


def _requires_gpu_runtime(options):
"""test_cpu 与 use_gpu_mode 正交地决定 GPU 运行时需求。"""
return bool(
not getattr(options, "test_cpu", False)
or getattr(options, "use_gpu_mode", False)
or _mode_runs_torch_gpu_reference(options)
)


def _resolve_dump_options(parser, options):
try:
options.use_dump, options.dump_dir = resolve_dump_options(
Expand Down Expand Up @@ -496,9 +517,7 @@ def _apply_single_config_gpu_defaults(options):

def _prepare_single_config_gpu(options):
normalize_accuracy_stable_dual_gpu_options(options)
if getattr(options, "accuracy_stable_dual_gpu", False) and getattr(options, "test_cpu", False):
raise ValueError("--accuracy_stable_dual_gpu=True does not support --test_cpu=True")
if options.test_cpu:
if not _requires_gpu_runtime(options):
options.gpu_workers_per_gpu_map = {}
options.gpu_total_memory_map = {}
options.runtime_config = TestRuntimeConfig.from_options(options)
Expand Down Expand Up @@ -1074,7 +1093,7 @@ def main():
)
return
normalize_accuracy_stable_dual_gpu_options(options)
if options.api_config and not options.test_cpu:
if options.api_config and _requires_gpu_runtime(options):
_apply_single_config_gpu_defaults(options)

mode = [
Expand Down
31 changes: 25 additions & 6 deletions engineV4.py
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,29 @@ def normalize_accuracy_stable_dual_gpu_options(options):
options.accuracy_stable = True


def _mode_runs_torch_gpu_reference(options):
"""只有执行 Torch reference 的模式才要求保留 GPU 运行时。"""
return any(
getattr(options, mode, False)
for mode in (
"accuracy",
"accuracy_stable",
"accuracy_stable_dual_gpu",
"torch_gpu_performance",
"paddle_torch_gpu_performance",
)
)


def _requires_gpu_runtime(options):
"""test_cpu 与 use_gpu_mode 正交地决定 GPU 运行时需求。"""
return bool(
not getattr(options, "test_cpu", False)
or getattr(options, "use_gpu_mode", False)
or _mode_runs_torch_gpu_reference(options)
)


def validate_gpu_options(options) -> tuple:
"""Validate and normalize GPU-related options."""
normalize_accuracy_stable_dual_gpu_options(options)
Expand Down Expand Up @@ -1162,8 +1185,6 @@ def validate_gpu_options(options) -> tuple:
"expected -1 or a positive integer"
)
if getattr(options, "accuracy_stable_dual_gpu", False):
if getattr(options, "test_cpu", False):
raise ValueError("--accuracy_stable_dual_gpu=True does not support --test_cpu=True")
if options.num_gpus < 2 or options.num_gpus % 2:
raise ValueError("--accuracy_stable_dual_gpu=True requires an even --num_gpus")
if options.num_workers_per_gpu != 1:
Expand Down Expand Up @@ -1205,9 +1226,7 @@ def _apply_single_config_gpu_defaults(options):

def _prepare_single_config_gpu(options):
normalize_accuracy_stable_dual_gpu_options(options)
if getattr(options, "accuracy_stable_dual_gpu", False) and getattr(options, "test_cpu", False):
raise ValueError("--accuracy_stable_dual_gpu=True does not support --test_cpu=True")
if options.test_cpu:
if not _requires_gpu_runtime(options):
options.gpu_workers_per_gpu_map = {}
options.gpu_total_memory_map = {}
options.runtime_config = TestRuntimeConfig.from_options(options)
Expand Down Expand Up @@ -1745,7 +1764,7 @@ def main():
)
return
normalize_accuracy_stable_dual_gpu_options(options)
if options.api_config and not options.test_cpu:
if options.api_config and _requires_gpu_runtime(options):
_apply_single_config_gpu_defaults(options)

mode = [
Expand Down
40 changes: 35 additions & 5 deletions tester/api_config/config_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,31 @@ def get_cached_numpy(self, dtype, shape, generation_kind="input", scale=1.2):
return get_cached_numpy_array(dtype, shape, generation_kind=generation_kind, scale=scale)

def _use_gpu(self, api_config=None, dtype=None):
"""判断是否启用 GPU tensor 生成;不代表 Paddle kernel 的 place。"""
if not is_gpu_mode():
return False
if self.place is not None and "cpu" in str(self.place).lower():
return False
return "gpu" in paddle.device.get_device()

def _paddle_kernel_uses_gpu(self, api_config):
"""test_cpu 只决定 Paddle kernel,不能被 use_gpu_mode 覆盖。"""
if self.place is not None and "cpu" in str(self.place).lower():
return False
if getattr(api_config, "test_cpu", False):
return False
return "gpu" in paddle.device.get_device()

def _torch_source_device_for_paddle(self, api_config):
"""返回送入 Paddle 前的 Torch 源设备,遵守 Paddle kernel place。"""
if self.place is not None and "cpu" in str(self.place).lower():
return torch.device("cpu")
if getattr(api_config, "test_cpu", False):
return torch.device("cpu")
if self._paddle_kernel_uses_gpu(api_config):
return torch.device("cuda", torch.cuda.current_device())
return torch.device("cpu")

def _supports_autograd(self, dtype=None):
dtype = dtype or self.dtype
return dtype in AUTOGRAD_DTYPES
Expand Down Expand Up @@ -3433,10 +3452,12 @@ def get_paddle_tensor(self, api_config):
and self._use_gpu(api_config)
):
self.paddle_tensor = self._make_gpu_paddle_tensor(api_config)
if getattr(api_config, "test_cpu", False):
self.paddle_tensor = self.paddle_tensor._copy_to(paddle.CPUPlace(), False)
return self.paddle_tensor
if self.cpu_tensor is not None:
torch_tensor = self.cpu_tensor.to(
device=torch.device("cuda:0") if self._use_gpu(api_config) else "cpu",
device=self._torch_source_device_for_paddle(api_config),
copy=True,
)
self.paddle_tensor = paddle.utils.dlpack.from_dlpack(
Expand All @@ -3445,7 +3466,10 @@ def get_paddle_tensor(self, api_config):
self.paddle_tensor.stop_gradient = not self._requires_autograd(api_config)
return self.paddle_tensor
if self.numpy_tensor is None and self._use_gpu(api_config):
return self.get_gpu_paddle_tensor(api_config)
tensor = self.get_gpu_paddle_tensor(api_config)
if getattr(api_config, "test_cpu", False):
self.paddle_tensor = tensor._copy_to(paddle.CPUPlace(), False)
return self.paddle_tensor
if not self.is_contiguous and self.strides is not None:
self.paddle_tensor = self._create_strided_paddle_tensor(api_config)
print(
Expand All @@ -3462,10 +3486,13 @@ def get_paddle_tensor(self, api_config):
if self.dtype == "bfloat16"
else ("float16" if self.dtype in FLOAT8_DTYPES else self.dtype)
)
operator_place = (
paddle.CPUPlace() if getattr(api_config, "test_cpu", False) else self.place
)
self.paddle_tensor = paddle.to_tensor(
self.get_numpy_tensor(api_config),
dtype=intermediate_dtype,
place=self.place,
place=operator_place,
)

if self.dtype == "bfloat16":
Expand Down Expand Up @@ -3497,18 +3524,21 @@ def _create_strided_paddle_tensor(self, api_config):
try:
intermediate_dtype = "float16" if self.dtype in FLOAT8_DTYPES else self.dtype
storage_size = self._strided_storage_size()
operator_place = (
paddle.CPUPlace() if getattr(api_config, "test_cpu", False) else self.place
)
flat_tensor = paddle.zeros(
[storage_size],
dtype=intermediate_dtype,
device=self.place,
device=operator_place,
)
tensor = paddle.as_strided(flat_tensor, self.shape, self.strides)
logical_tensor = self.get_numpy_tensor(api_config)
if logical_tensor.size > 0:
tensor[...] = paddle.to_tensor(
logical_tensor,
dtype=intermediate_dtype,
place=self.place,
place=operator_place,
)
if self.dtype in FLOAT8_DTYPES:
flat_tensor = paddle.cast(flat_tensor, dtype=self.dtype)
Expand Down
17 changes: 17 additions & 0 deletions tester/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,12 @@ def get_arg(api_config, arg_pos, arg_name, default=None):
# differs materially from any public API.
no_signature_api_mappings.update(
{
# copy_ 是内建方法,无法通过 inspect 获取签名。
"paddle.Tensor.copy_": {
"self": lambda cfg: get_arg(cfg, 0, "self"),
"other": lambda cfg: get_arg(cfg, 1, "other"),
"blocking": lambda cfg: get_arg(cfg, 2, "blocking", True),
},
# adamw_(param, grad, lr, moment1, moment2, moment2_max,
# beta1_pow, beta2_pow, master_param, skip_update,
# beta1, beta2, epsilon, lr_ratio, coeff, with_decay,
Expand Down Expand Up @@ -493,8 +499,11 @@ class APITestBase:
def __init__(self, api_config, use_torch=True, runtime_config=None):
self.api_config = api_config
self.api_config.use_torch = use_torch
self.use_torch = bool(use_torch)
self.runtime_config = runtime_config or TestRuntimeConfig()
self.gpu_mode_config = self.runtime_config.gpu_mode
# TensorConfig 需要知道 kernel place,不能从 GPU mode 反推。
self.api_config.test_cpu = self.runtime_config.test_cpu
self.dump_context = (
DumpContext(
os.environ.get("DUMP_DIR") or DEFAULT_DUMP_DIR, api_config=api_config.config
Expand All @@ -508,6 +517,14 @@ def __init__(self, api_config, use_torch=True, runtime_config=None):
torch.set_num_threads(8)
torch.set_printoptions(threshold=100, linewidth=120)

def torch_operator_device(self):
"""返回当前 worker 的 Torch reference 设备。"""
return torch.device(f"{self.runtime_config.torch_operator_device_type}:0")

def requires_gpu_runtime(self):
"""算子执行或 GPU mode 任一需要 GPU 时返回 True。"""
return self.use_torch or not self.runtime_config.test_cpu or self.gpu_mode_config.enabled

def run_with_dump(self):
"""Execute the test with dump output capture and lifecycle reporting."""
if self.dump_context is None:
Expand Down
1 change: 1 addition & 0 deletions tester/base_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ handle_axes_api:

forward_only_apis:
- _run_custom_op
- copy_
- moe_permute
- moe_unpermute
- fp8_quant_blockwise
Expand Down
22 changes: 19 additions & 3 deletions tester/log_writer/log_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,32 @@ def print_run_header(options, paddle_version):
)
)

torch_reference_gpu = any(
getattr(options, name, False)
for name in (
"accuracy",
"accuracy_stable",
"accuracy_stable_dual_gpu",
"torch_gpu_performance",
"paddle_torch_gpu_performance",
)
)
requires_gpu = not options.test_cpu or options.use_gpu_mode or torch_reference_gpu
compute = [
("paddle_kernel_device", "CPU" if options.test_cpu else "GPU"),
("torch_reference_device", "GPU" if torch_reference_gpu else "N/A"),
("input_compare_device", "GPU" if options.use_gpu_mode else "CPU"),
]
if options.test_cpu:
compute = [("--test_cpu", True)]
else:
compute.append(("--test_cpu", True))
if requires_gpu:
if not options.gpu_ids:
gpu_ids_display = "all visible"
elif options.gpu_ids == "-1":
gpu_ids_display = "-1 (all visible)"
else:
gpu_ids_display = options.gpu_ids
compute = [("--gpu_ids", gpu_ids_display)]
compute.append(("--gpu_ids", gpu_ids_display))
if options.use_gpu_mode:
compute.append(("--use_gpu_mode", True))
if getattr(options, "accuracy_stable_dual_gpu", False):
Expand Down
7 changes: 6 additions & 1 deletion tester/paddle_cinn_vs_dygraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@

class APITestCINNVSDygraph(APITestBase):
def __init__(self, api_config, **kwargs):
super().__init__(api_config)
# CINN 只执行 Paddle kernel,不应丢失 worker 的 test_cpu 设备协议。
super().__init__(
api_config,
use_torch=False,
runtime_config=kwargs.get("runtime_config"),
)
self.test_amp = kwargs.get("test_amp", False)
self.test_backward = kwargs.get("test_backward", False)

Expand Down
43 changes: 43 additions & 0 deletions tester/paddle_to_torch/mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -5049,5 +5049,48 @@
},
"paddle._C_ops._run_custom_op": {
"Rule": "CopsRunCustomOpRule"
},
"paddle.Tensor.add_": {
"Rule": "CopsAdd_Rule"
},
"paddle.Tensor.contiguous": {
"torch_api": "torch.Tensor.contiguous"
},
"paddle.Tensor.copy_": {
"torch_api": "torch.Tensor.copy_",
"torch_args": [],
"torch_kwargs": {
"other": "other",
"non_blocking": "not blocking"
}
},
"paddle.Tensor.flatten_": {
"Rule": "CopsFlatten_Rule"
},
"paddle.Tensor.multiply_": {
"Rule": "CopsMultiply_Rule"
},
"paddle.Tensor.put_along_axis_": {
"Rule": "CopsPutAlongAxis_Rule"
},
"paddle.Tensor.scale_": {
"Rule": "CopsScale_Rule"
},
"paddle.Tensor.subtract_": {
"Rule": "CopsSubtract_Rule"
},
"paddle.Tensor.to": {
"Rule": "TensorToRule"
},
"paddle.randint": {
"torch_api": "torch.randint",
"torch_args": [
"low",
"high",
"tuple(shape) if isinstance(shape, list) else shape"
],
"torch_kwargs": {
"dtype": "locals().get(\"dtype\") if locals().get(\"dtype\") is not None else torch.int64"
}
}
}
Loading
Loading